카테고리 없음

[c#] 델리게이트 : 술어 vs. 액션 vs. Func

행복을전해요 2020. 12. 31. 03:49
  • Predicate: essentially Func<T, bool>; asks the question "does the specified argument satisfy the condition represented by the delegate?" Used in things like List.FindAll.

  • Action: Perform an action given the arguments. Very general purpose. Not used much in LINQ as it implies side-effects, basically.

  • Func: Used extensively in LINQ, usually to transform the argument, e.g. by projecting a complex structure to one property.

Other important delegates:

  • EventHandler/EventHandler<T>: Used all over WinForms

  • Comparison<T>: Like IComparer<T> but in delegate form.

-------------------

Action, Func and Predicate all belong to the delegate family.

Action : 액션은 n 개의 입력 매개 변수를 사용할 수 있지만 void를 반환합니다.

Func: Func는 n 개의 입력 매개 변수를 사용할 수 있지만 항상 제공된 유형의 결과를 반환합니다. Func<T1,T2,T3,TResult>, 여기서 T1, T2, T3은 입력 매개 변수이고 TResult는 그 출력입니다.

Predicate: 술어도 Func의 한 형태이지만 항상 bool을 반환합니다. 간단히 말해서 Func<T,bool>.

-------------------

Jon의 답변 외에도

  • Converter<TInput, TOutput>: 본질적 Func<TInput, TOutput>으로이지만 의미론이 있습니다. List.ConvertAll 및 Array.ConvertAll에서 사용하지만 개인적으로 다른 곳에서는 본 적이 없습니다.
-------------------

MethodInvoker는 WinForms 개발자가 사용할 수있는 것입니다. 인수를받지 않고 결과를 반환하지 않습니다. 이는 Action보다 선행하며 BeginInvoke () 등이 형식화되지 않은 델리게이트를 수락하기 때문에 UI 스레드를 호출 할 때 여전히 자주 사용됩니다. Action도 마찬가지입니다.

myForm.BeginInvoke((MethodInvoker)delegate
{
  MessageBox.Show("Hello, world...");
  });
  

또한 ThreadStart와 ParameterizedThreadStart에 대해서도 알고 있습니다. 다시 말하지만 대부분의 사람들은 요즘 액션을 대체 할 것입니다.

-------------------

Predicate, Func 및 Action은 .NET의 기본 대리자 인스턴스입니다. 이러한 각 대리자 인스턴스는 특정 서명이있는 사용자 메서드를 참조하거나 가리킬 수 있습니다.

액션 델리게이트-액션 델리게이트 인스턴스는 인자를 받고 void를 반환하는 메서드를 가리킬 수 있습니다.

Func 대리자-Func 대리자 인스턴스는 가변 개수의 인수를 사용하고 일부 형식을 반환하는 메서드를 가리킬 수 있습니다.

술어-술어는 func 대리자 인스턴스와 유사하며 가변 개수의 인수를 취하고 bool 형식을 반환하는 메서드를 가리킬 수 있습니다.

-------------------

인수와 각 유형에 대한 간단한 예

이 Func는 두 개의 int 인수를 취하고 int를 반환합니다.

 Func<int, int, int> sum = (a, b) => a + b;
 Console.WriteLine(sum(3, 5));//Print 8
 

이 경우 func에는 인수가 없지만 문자열을 반환합니다.

Func<string> print = () => "Hello world";
Console.WriteLine(print());//Print Hello world

이 Action은 두 개의 int 인수를 취하고 void를 반환합니다.

Action<int, int> displayInput = (x, y) => Console.WriteLine("First number is :" + x + " , Second number is "+ y);
displayInput(4, 6); //Print First number is :4 , Second number is :6

이 술어는 하나의 인수를 취하고 항상 bool을 리턴합니다. 일반적으로 술어는 항상 bool을 리턴합니다.

Predicate<int> isPositive = (x) => x > 0;
Console.WriteLine(isPositive(5));//Print True
-------------------

람다를 사용한 동작 및 기능 :

person p = new person();
Action<int, int> mydel = p.add;       /*(int a, int b) => { Console.WriteLine(a + b); };*/
Func<string, string> mydel1 = p.conc; /*(string s) => { return "hello" + s; };*/
mydel(2, 3);
string s1=  mydel1(" Akhil");
Console.WriteLine(s1);
Console.ReadLine();
-------------------

Func는 LINQ에 더 친숙하며 매개 변수로 전달할 수 있습니다. (포인트 프리)

술어는 할 수 없으며 다시 래핑해야합니다.

Predicate<int> IsPositivePred = i => i > 0;
Func<int,bool> IsPositiveFunc = i => i > 0;

new []{2,-4}.Where(i=>IsPositivePred(i)); //Wrap again

new []{2,-4}.Where(IsPositivePred);  //Compile Error
new []{2,-4}.Where(IsPositiveFunc);  //Func as Parameter


출처
https://stackoverflow.com/questions/2002918