C# Language Le func , Action et prédicat types de délégué


Exemple

L'espace de noms Système contient les types de délégué Func<..., TResult> avec entre 0 et 15 paramètres génériques, renvoyant le type TResult .

private void UseFunc(Func<string> func)
{
    string output = func(); // Func with a single generic type parameter returns that type
    Console.WriteLine(output);
}

private void UseFunc(Func<int, int, string> func)
{
    string output = func(4, 2); // Func with multiple generic type parameters takes all but the first as parameters of that type
    Console.WriteLine(output);
}

L'espace de noms Système contient également des types de délégués Action<...> avec un nombre différent de paramètres génériques (de 0 à 16). Il est similaire à Func<T1, .., Tn> , mais il renvoie toujours un void .

private void UseAction(Action action)
{
    action(); // The non-generic Action has no parameters
}

private void UseAction(Action<int, string> action)
{
    action(4, "two"); // The generic action is invoked with parameters matching its type arguments
}

Predicate<T> est également une forme de Func mais il renverra toujours bool . Un prédicat est un moyen de spécifier un critère personnalisé. En fonction de la valeur de l'entrée et de la logique définie dans le prédicat, elle retournera soit true soit false . Predicate<T> se comporte donc comme Func<T, bool> et les deux peuvent être initialisés et utilisés de la même manière.

Predicate<string> predicate = s => s.StartsWith("a");
Func<string, bool> func = s => s.StartsWith("a");

// Both of these return true
var predicateReturnsTrue = predicate("abc");
var funcReturnsTrue = func("abc");

// Both of these return false
var predicateReturnsFalse = predicate("xyz");
var funcReturnsFalse = func("xyz");

Le choix d'utiliser ou non Predicate<T> ou Func<T, bool> est vraiment une question d'opinion. Predicate<T> est sans doute plus expressif de l'intention de l'auteur, tandis que Func<T, bool> est susceptible d'être familier à une plus grande proportion de développeurs C #.

En plus de cela, il existe certains cas où une seule des options est disponible, en particulier lors de l'interaction avec une autre API. Par exemple, List<T> et Array<T> prennent généralement Predicate<T> pour leurs méthodes, tandis que la plupart des extensions LINQ n'acceptent que Func<T, bool> .