development

C #에서 액션 대리자의 사용

big-blog 2020. 6. 29. 07:32
반응형

C #에서 액션 대리자의 사용


나는 C #의 Action Delegates와 더 많은 것을 배우고 그들이 유용 할 수있는 곳을 생각하기 위해 노력하고있었습니다.

아무도 행동 대리인을 사용 했습니까? 그렇다면 왜 그렇습니까? 또는 유용한 예제를 줄 수 있습니까?


MSDN의 말 :

이 대리자는 Array.ForEach 메서드와 List.ForEach 메서드에서 배열 또는 목록의 각 요소에 대한 작업을 수행하는 데 사용됩니다.

그 외에는 값을 반환하지 않고 1-3 개의 매개 변수를 사용하는 일반 대리자로 사용할 수 있습니다.


다음은 Action 대리자의 유용성을 보여주는 작은 예입니다.

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Action<String> print = new Action<String>(Program.Print);

        List<String> names = new List<String> { "andrew", "nicole" };

        names.ForEach(print);

        Console.Read();
    }

    static void Print(String s)
    {
        Console.WriteLine(s);
    }
}

foreach 메소드는 이름 콜렉션을 반복하고 콜렉션의 print각 멤버에 대해 메소드를 실행합니다 . 보다 기능적인 스타일의 프로그래밍으로 나아가면서 C # 개발자에게는 약간의 패러다임 전환이 있습니다. (컴퓨터 과학에 대한 자세한 내용은 http://en.wikipedia.org/wiki/Map_(higher-order_function)을 참조하십시오 .

이제 C # 3을 사용하는 경우 다음과 같이 람다 식으로 약간 쓸어 넘길 수 있습니다.

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<String> names = new List<String> { "andrew", "nicole" };

        names.ForEach(s => Console.WriteLine(s));

        Console.Read();
    }
}

스위치가 있으면 할 수있는 일이 하나 있습니다.

switch(SomeEnum)
{
  case SomeEnum.One:
      DoThings(someUser);
      break;
  case SomeEnum.Two:
      DoSomethingElse(someUser);
      break;
}

강력한 액션을 통해 해당 스위치를 사전으로 바꿀 수 있습니다.

Dictionary<SomeEnum, Action<User>> methodList = 
    new Dictionary<SomeEnum, Action<User>>()

methodList.Add(SomeEnum.One, DoSomething);
methodList.Add(SomeEnum.Two, DoSomethingElse); 

...

methodList[SomeEnum](someUser);

또는 더 멀리 가져갈 수 있습니다.

SomeOtherMethod(Action<User> someMethodToUse, User someUser)
{
    someMethodToUse(someUser);
}  

....

var neededMethod = methodList[SomeEnum];
SomeOtherMethod(neededMethod, someUser);

몇 가지 예만 있습니다. 물론 Linq 확장 방법이 더 분명하게 사용됩니다.


짧은 이벤트 핸들러에 대한 조치를 사용할 수 있습니다.

btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!");

프로젝트에서 다음과 같은 액션 대리자를 사용했습니다.

private static Dictionary<Type, Action<Control>> controldefaults = new Dictionary<Type, Action<Control>>() { 
            {typeof(TextBox), c => ((TextBox)c).Clear()},
            {typeof(CheckBox), c => ((CheckBox)c).Checked = false},
            {typeof(ListBox), c => ((ListBox)c).Items.Clear()},
            {typeof(RadioButton), c => ((RadioButton)c).Checked = false},
            {typeof(GroupBox), c => ((GroupBox)c).Controls.ClearControls()},
            {typeof(Panel), c => ((Panel)c).Controls.ClearControls()}
    };

which all it does is store a action(method call) against a type of control so that you can clear all the controls on a form back to there defaults.


For an example of how Action<> is used.

Console.WriteLine has a signature that satisifies Action<string>.

    static void Main(string[] args)
    {
        string[] words = "This is as easy as it looks".Split(' ');

        // Passing WriteLine as the action
        Array.ForEach(words, Console.WriteLine);         
    }

Hope this helps


I use it when I am dealing with Illegal Cross Thread Calls For example:

DataRow dr = GetRow();
this.Invoke(new Action(() => {
   txtFname.Text = dr["Fname"].ToString();
   txtLname.Text = dr["Lname"].ToString(); 
   txtMI.Text = dr["MI"].ToString();
   txtSSN.Text = dr["SSN"].ToString();
   txtSSN.ButtonsRight["OpenDialog"].Visible = true;
   txtSSN.ButtonsRight["ListSSN"].Visible = true;
   txtSSN.Focus();
}));

I must give credit to Reed Copsey SO user 65358 for the solution. My full question with answers is SO Question 2587930


I used it as a callback in an event handler. When I raise the event, I pass in a method taking a string a parameter. This is what the raising of the event looks like:

SpecialRequest(this,
    new BalieEventArgs 
    { 
            Message = "A Message", 
            Action = UpdateMethod, 
            Data = someDataObject 
    });

The Method:

   public void UpdateMethod(string SpecialCode){ }

The is the class declaration of the event Args:

public class MyEventArgs : EventArgs
    {
        public string Message;
        public object Data;
        public Action<String> Action;
    }

This way I can call the method passed from the event handler with a some parameter to update the data. I use this to request some information from the user.


We use a lot of Action delegate functionality in tests. When we need to build some default object and later need to modify it. I made little example. To build default person (John Doe) object we use BuildPerson() function. Later we add Jane Doe too, but we modify her birthdate and name and height.

public class Program
{
        public static void Main(string[] args)
        {
            var person1 = BuildPerson();

            Console.WriteLine(person1.Firstname);
            Console.WriteLine(person1.Lastname);
            Console.WriteLine(person1.BirthDate);
            Console.WriteLine(person1.Height);

            var person2 = BuildPerson(p =>
            {
                p.Firstname = "Jane";
                p.BirthDate = DateTime.Today;
                p.Height = 1.76;
            });

            Console.WriteLine(person2.Firstname);
            Console.WriteLine(person2.Lastname);
            Console.WriteLine(person2.BirthDate);
            Console.WriteLine(person2.Height);

            Console.Read();
        }

        public static Person BuildPerson(Action<Person> overrideAction = null)
        {
            var person = new Person()
            {
                Firstname = "John",
                Lastname = "Doe",
                BirthDate = new DateTime(2012, 2, 2)
            };

            if (overrideAction != null)
                overrideAction(person);

            return person;
        }
    }

    public class Person
    {
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public DateTime BirthDate { get; set; }
        public double Height { get; set; }
    }

참고URL : https://stackoverflow.com/questions/371054/uses-of-action-delegate-in-c-sharp

반응형