11
votes

Fermetures et Lambda en C #

Je reçois les principes de base des fermetures et des expressions de Lambda, mais j'essaie d'envelopper mon esprit autour de ce qui se passe dans les coulisses et quand il est / n'est pas pratique de les utiliser dans mon code. Considérez l'exemple suivant, qui prend une collection de noms et renvoie tous les noms qui commencent par la lettre C ...

    static void Main(string[] args)
    {
        List<string> names = new List<string>();
        names.AddRange(new string[]
        {
            "Alan", "Bob", "Chris", "Dave", "Edgar", "Frank"
        });


        names.FindAll(x => x.StartsWith("C")).ForEach(
            i => Console.WriteLine(i));

    }


0 commentaires

5 Réponses :


15
votes

Oui, Windowall créera une nouvelle liste. Vous voulez "où", qui retournera un objet iEnumerable qui sait comment boucler sur votre liste existante: xxx

mais il n'y a pas de fermeture dans ce code, car il n'y a pas de variable locale à capturer. < / p>


2 commentaires

OK, alors peut-être que je ne reçois pas encore les bases des fermetures. Néanmoins, toutes les réponses que je suis arrivée ici sont super et me mobilisent un peu plus loin sur la route ... merci, tout le monde.


Cela m'explique la différence entre la fermeture et la Lambda: "Pas de fermeture dans ce code, car il n'y a pas de variable locale à capturer."



2
votes

Vous devez utiliser au lieu de retranchez . iratera sur la collection pour votre état et vous permettra d'exécuter votre action plutôt que de créer une nouvelle collection qui répond à votre condition, puis de l'exécution de votre action.


0 commentaires

2
votes

Vous avez raison que l'utilisation de la liste .Findall code> créera et renvoie une nouvelle liste code>.

Si vous êtes capable Pour utiliser Linq, il existe de nombreuses méthodes qui diffèrent leurs résultats un élément à la fois, dans la mesure du possible, plutôt que de renvoyer une collection entièrement peuplée: p> xxx pré>

Il n'y a pas intégré à foreach code> méthode qui agit sur ienumerable code>, mais il est trivial pour écrire votre propre extension si vous avez vraiment besoin de cette fonctionnalité: P>

names.Where(x => x.StartsWith("C")).ForEach(Console.WriteLine);

// ...

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (T item in source)
    {
        action(item);
    }
}


1 commentaires

C'est exactement comment j'allais le faire. J'aurais également mentionné que la création de liste peut être simplifiée: Liste noms = nouvelle liste {"Alan", "Bob", "Chris", "Dave", "Edgar", "Frank "};



12
votes

Les autres réponses qui disent à utiliser "où" sont correctes. Un point supplémentaire: vous pouvez également utiliser la syntaxe de compréhension de la requête pour faire le "Où" plus agréable:

   var query = from name in names where name.StartsWith("C") select name;
   foreach(var result in query) Console.WriteLine(result);


0 commentaires

0
votes

Qu'est-ce qui rend une expression spécifique spécifiquement une fermeture est un scopage lexical, non?

xxx

ou même

xxx

ou je manque quelque chose ou fais-je des hypothèses injusculées?


0 commentaires