Func vs. Action vs. Predicate [duplicate]

To pytanie ma już odpowiedź tutaj:

Z prawdziwymi przykładami i ich wykorzystaniem, czy ktoś może mi pomóc zrozumieć:

  1. Kiedy potrzebujemy Func delegata?
  2. Kiedy potrzebujemy delegata akcji?
  3. Kiedy potrzebujemy predykatów?
 620
Author: Reese Moore, 2010-11-30

3 answers

Różnica między Func i Action polega po prostu na tym, czy chcesz, aby delegat zwrócił wartość (użyj Func) czy nie (Użyj Action).

Func jest prawdopodobnie najczęściej używany w LINQ - na przykład w projekcjach:

 list.Select(x => x.SomeProperty)

Lub filtrowanie:

 list.Where(x => x.SomeValue == someOtherValue)

Lub wybór klucza:

 list.Join(otherList, x => x.FirstKey, y => y.SecondKey, ...)

Action jest częściej używany do rzeczy takich jak List<T>.ForEach: wykonaj podaną akcję dla każdego elementu na liście. Używam tego rzadziej niż Func, chociaż czy czasami używam wersja bez parametru dla takich rzeczy jak Control.BeginInvoke i Dispatcher.BeginInvoke.

Predicate to tylko specjalny przypadek Func<T, bool>, wprowadzony przed wszystkimi Func i większością Action delegatów przyszedł. Podejrzewam, że gdybyśmy mieli już Func i Action w ich różnych odsłonach, Predicate nie zostalibyśmy przedstawieni... chociaż nie nadaje pewne znaczenie użyciu delegata, podczas gdy Func i Action są używane do bardzo różnych celów.

Predicate stosowany jest głównie w List<T> dla metod takich jak FindAll i RemoveAll.

 792
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-14 03:55:15

Action {[3] } Jest delegatem (wskaźnikiem) do metody, która pobiera zero, jeden lub więcej parametrów wejściowych, ale niczego nie zwraca.

Func Jest delegatem (wskaźnikiem) do metody, który pobiera zero, jeden lub więcej parametrów wejściowych i zwraca wartość (lub odniesienie).

Predykat jest specjalnym rodzajem Func często używanym do porównań.

Choć szeroko stosowane w Linq, Action i Func są pojęciami logicznie niezależnymi od Linq. C++ zawiera już podstawowe pojęcie w postaci typowanych wskaźników funkcji.

Oto mały przykład działania i Func bez użycia Linq:

class Program
{
    static void Main(string[] args)
    {
        Action<int> myAction = new Action<int>(DoSomething);
        myAction(123);           // Prints out "123"
                                 // can be also called as myAction.Invoke(123);

        Func<int, double> myFunc = new Func<int, double>(CalculateSomething);
        Console.WriteLine(myFunc(5));   // Prints out "2.5"
    }

    static void DoSomething(int i)
    {
        Console.WriteLine(i);
    }

    static double CalculateSomething(int i)
    {
        return (double)i/2;
    }
}
 314
Author: Knasterbax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-08 21:04:16

Func - Gdy chcesz mieć delegata dla funkcji, która może przyjmować parametry i zwraca wartość. Najczęstszym przykładem może być Select from LINQ:

var result = someCollection.Select( x => new { x.Name, x.Address });

Action - Gdy chcesz delegata dla funkcji, która może przyjmować parametry i nie zwraca wartości. Używam ich często do anonimowych obsługi zdarzeń:

button1.Click += (sender, e) => { /* Do Some Work */ }

Predykat - Gdy chcesz mieć wyspecjalizowaną wersję Func, która ocenia wartość według zestawu kryteriów i zwraca wynik logiczny(true dla dopasowania, false w przeciwnym razie). ponownie, są one używane w LINQ dość często do takich rzeczy jak Where:

var filteredResults = 
    someCollection.Where(x => x.someCriteriaHolder == someCriteria);

Właśnie sprawdziłem i okazało się, że LINQ nie używa predykatów. Nie wiem, dlaczego podjęli taką decyzję...ale teoretycznie jest to nadal sytuacja, w której orzeczenie pasowałoby.

 57
Author: Justin Niessner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-25 11:17:39