Делегати: предикат проти дії проти функц


137

Чи може хтось дати гарне пояснення (сподіваємось, приклади) цих 3 найважливіших делегатів:

  • Присудок
  • Дія
  • Функц

Відповіді:


180
  • Predicate: по суті Func<T, bool>; задає питання "чи відповідає зазначений аргумент умові, представленій делегатом?" Використовується в таких речах, як List.FindAll.

  • Action: Виконай дії з аргументами. Дуже загальне призначення. Не використовується багато в LINQ, оскільки в основному це передбачає побічні ефекти.

  • Func: Широко використовується в LINQ, як правило, для перетворення аргументу, наприклад, проектуючи складну структуру на одне властивість.

Інші важливі делегати:

  • EventHandler/ EventHandler<T>: Використовується в усіх WinForms

  • Comparison<T>: Як, IComparer<T>але у формі делегата


3
Є також System.Converter<TInput, TOutput>, хоча він рідко використовується.
G-Wiz

4
Конвертер - хороший делегат, коли потрібно багато перетворення моделі в бізнес-класи, тобто stum.de/2009/12/23/…
Michael

EventHandler/EventHandler<T>з'являються також і поза межами WinForms.
Енді

@Andy: Дещо ... Але менше, наприклад, у WPF. Я погоджуюся, що для цього немає нічого конкретного WinForms.
Джон Скіт

48

Action, Funcі Predicateвсі належать родині делегатов.

Action : Дія може приймати n вхідних параметрів, але вона повертає недійсність.

Func: Func може приймати n вхідних параметрів, але завжди повертатиме результат наданого типу. Func<T1,T2,T3,TResult>, тут T1, T2, T3 - вхідні параметри, а TResult - вихід з нього.

Predicate: Присудок також є формою Func, але він завжди повертає bool. Простими словами - це обгортка Func<T,bool>.


Найкраща і найпростіша відповідь, яку я коли-небудь знайшов стосовно цього питання
Реян Чаугл,

@ReyanChougle: Рада, ви вважаєте це корисним.
Рахул Гарг

9

Окрім відповіді Йона, є також

  • Converter<TInput, TOutput>: По суті Func<TInput, TOutput>, але з семантикою. Використовується List.ConvertAll та Array.ConvertAll, але особисто я його більше ніде не бачив.

4

MethodInvoker - це той, який можуть використовувати розробники WinForms; він не приймає аргументів і не дає результатів. Він передує Action, і досі часто використовується при виклику на потік інтерфейсу, оскільки BeginInvoke () та ін приймають нетипізований Делегат; хоча Дія буде так само добре.

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

Я також був би в курсі ThreadStart і ParameterizedThreadStart; знову ж таки більшість людей замінить акцію в ці дні.


3

Предикат, функція та дія є вбудованими делегатними екземплярами .NET. Кожен з цих екземплярів-делегатов може посилатися або вказувати на користувацькі методи із певною підписом.

Делегат дій - екземпляри делегування дій можуть вказувати на методи, які беруть аргументи та повертають недійсні.

Делегат функцій - екземпляр делегата функцій може вказувати на методи (и), які приймають змінну кількість аргументів і повертають певний тип.

Предикат - предикати схожі на екземпляри функцій делегації, і вони можуть вказувати на методи, які беруть змінну кількість аргументів і повертають тип bool.


2

Дія та функція з лямбда:

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();

2

Функція більш зручна для 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

2

Простий приклад про аргументи та те, що повертає кожен тип

Цей функція приймає два int аргументи і повертає int.Func завжди має тип повернення

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

У цьому випадку функція не має аргументів, але повертає рядок

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

Ця дія бере два int аргументи і повертає недійсними

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.