Je sais que cela peut sembler étrange, mais je ne sais même pas comment rechercher cette syntaxe sur Internet et je ne suis pas sûr de ce que cela signifie exactement.
J'ai donc regardé du code MoreLINQ, puis j'ai remarqué cette méthode
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));
return _(); IEnumerable<TSource> _()
{
var knownKeys = new HashSet<TKey>(comparer);
foreach (var element in source)
{
if (knownKeys.Add(keySelector(element)))
yield return element;
}
}
}
Quelle est cette déclaration de retour étrange? return _();
?
return _(); IEnumerable<TSource> _()
:?return _(); IEnumerable<TSource> _()
que leyield return
?return _(); IEnumerable<TSource> _()
. Il pourrait être confus par son apparence plutôt que par la déclaration de retour réelle.Réponses:
C'est C # 7.0 qui prend en charge les fonctions locales ...
C # actuel avec
Func<T>
L'astuce est que _ () est déclaré après son utilisation, ce qui est parfaitement bien.
Utilisation pratique des fonctions locales
L'exemple ci-dessus est juste une démonstration de la façon dont la méthode en ligne peut être utilisée, mais très probablement si vous allez invoquer la méthode une seule fois, alors cela ne sert à rien.
Mais dans l'exemple ci-dessus, comme mentionné dans les commentaires de Phoshi et Luaan , il y a un avantage à utiliser la fonction locale. Puisque la fonction avec yield return ne sera exécutée que si quelqu'un l'itère, dans ce cas, la méthode en dehors de la fonction locale sera exécutée et la validation des paramètres sera effectuée même si personne n'itérera la valeur.
Plusieurs fois, nous avons répété du code dans la méthode, regardons cet exemple.
Je pourrais optimiser cela avec ...
la source
_AnonymousFunction
ou juste_
, alors que je m'attendrais à ce qu'une véritable fonction anonyme soit quelque chose comme(x,y) => x+y
. J'appellerais cela une fonction locale, mais je ne suis pas habitué à la terminologie C #.yield return
, aucun code n'est exécuté tant que l'énumérable n'est pas réellement énuméré. Ceci n'est pas souhaitable, car vous voulez par exemple vérifier les arguments tout de suite. La seule façon de faire cela en C # est de séparer la méthode en deux méthodes - l'une avecyield return
s et l'autre sans. Les méthodes en ligne vous permettent de déclarer layield
méthode using à l' intérieur , évitant ainsi l'encombrement et le mauvais usage potentiel d'une méthode strictement interne à son parent et non réutilisable.Prenons l'exemple le plus simple
_()
est une fonction locale déclarée dans la méthode contenant l'instruction return.la source