Pourquoi Func<T,bool> au lieu de Prédicat<T>?
C'est juste une curiosité question, je me demandais si quelqu'un avait une bonne réponse à:
Dans le .NET Framework Bibliothèque de Classe, nous avons par exemple ces deux méthodes:
public static IQueryable<TSource> Where<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, bool>> predicate
)
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
Pourquoi ont-ils utiliser Func<TSource, bool>
au lieu de Predicate<TSource>
? Semble que le Predicate<TSource>
n'est utilisé que par List<T>
et Array<T>
, tandis que Func<TSource, bool>
est utilisé par à peu près tous Queryable
et Enumerable
méthodes et les méthodes d'extension... qu'est-ce qui?
- Oh oui, le manque d'uniformité dans l'utilisation de ces lecteurs me fou trop.
Vous devez vous connecter pour publier un commentaire.
Tout
Predicate
a été introduit en même temps queList<T>
etArray<T>
, dans .net 2.0, les différentsFunc
etAction
variantes viennent .net 3.5.De sorte que ceux
Func
les prédicats sont utilisés principalement pour des raisons de cohérence dans les opérateurs LINQ. Comme de .net 3.5, sur l'utilisation deFunc<T>
etAction<T>
la directive unis:J'ai demandé cela avant. J'aime la
Predicate<T>
délégué - c'est agréable et descriptif. Cependant, vous devez tenir compte de la surcharge deWhere
:Qui vous permet de filtrer sur la base de l'indice de l'entrée ainsi. C'est agréable et cohérente, considérant ce qui suit:
ne serait pas.
Where
méthode d'extension estpredicate
. Heh =P.Sûrement la raison pour l'utilisation de
Func
au lieu d'un délégué spécifique est que C# traite séparément déclaré les délégués totalement différents types.Même si
Func<int, bool>
etPredicate<int>
les deux ont le même argument et types de retour, ils ne sont pas compatible avec l'assignation. Donc, si chaque bibliothèque a déclaré son propre type de délégué pour chaque modèle de délégué, ces bibliothèques ne serait pas en mesure d'interopérer, à moins que l'utilisateur insère la "transition" délégués d'effectuer des conversions.En encourageant tout le monde à utiliser la touche Func, Microsoft espère que cela va résoudre le problème de l'incompatibilité des types délégués. Tous les délégués jouent bien ensemble, parce qu'ils seront appariés sur la base de leurs paramètres/types de retour.
Il ne résout pas tous les problèmes, car
Func
(etAction
) ne peut pas avoirout
ouref
paramètres, mais ceux qui sont moins fréquemment utilisés.Mise à jour: dans les commentaires Svish dit:
Oui, aussi longtemps que votre programme n'attribue méthodes pour les délégués, comme dans la première ligne de mon
Main
fonction. Le compilateur silencieusement génère un code à nouveau un délégué de l'objet qui la transmet à la méthode. Donc, à monMain
fonction, je pourrais changer dex1
pour être de typeExceptionHandler2
sans causer un problème.Cependant, sur la deuxième ligne j'essaie d'attribuer le premier délégué à un autre délégué. Même pensé que 2e délégué type a exactement le même paramètre et types de retour, le compilateur donne erreur
CS0029: Cannot implicitly convert type 'ExceptionHandler1' to 'ExceptionHandler2'
.Peut-être cela va le rendre plus clair:
Ma méthode
IsNegative
est une très bonne chose pour l'attribuer à lap
etf
variables, aussi longtemps que je le faire directement. Mais alors je ne peux pas attribuer un de ces variables à l'autre.Func<T, bool>
ouPredicate<T>
plutôt que d'avoir le type inféré par le compilateur.Les conseils (en 3.5 et ci-dessus) est d'utiliser la
Action<...>
etFunc<...>
- pour le "pourquoi?" - l'avantage est que la "Predicate<T>
" n'a de sens que si vous savez ce que "prédicat" signifie - sinon, vous avez besoin de regarder l'objet navigateur (etc) pour trouver la signatute.À l'inverse
Func<T,bool>
selon un modèle normalisé; je peux le dire immédiatement que c'est une fonction qui prend unT
et renvoie unbool
- n'ont pas besoin de comprendre toute la terminologie - il suffit d'appliquer ma vérité test.Pour "prédicat", ça aurait été OK, mais j'apprécie la tentative de standardiser. Il permet aussi beaucoup de la parité avec les méthodes associées dans ce domaine.