web-dev-qa-db-fra.com

Code équivalent au mot clé 'let' dans les appels de méthode d'extension LINQ chaînés

À l'aide des fonctionnalités de compréhension de requête des compilateurs C #, vous pouvez écrire du code tel que:

var names = new string[] { "Dog", "Cat", "Giraffe", "Monkey", "Tortoise" };
var result =
    from animalName in names
    let nameLength = animalName.Length
    where nameLength > 3
    orderby nameLength
    select animalName; 

Dans l'expression de requête ci-dessus, le mot clé let permet de transmettre une valeur aux opérations where et orderby sans appel dupliqué à animalName.Length.

Quel est le jeu équivalent d'appels de méthode d'extension LINQ permettant d'obtenir ce que le mot clé "let" fait ici?

184
LBushkin

Let n'a pas son propre fonctionnement; il se greffe de Select. Vous pouvez voir cela si vous utilisez "réflecteur" pour séparer une dll existante.

ce sera quelque chose comme:

var result = names
        .Select(animalName => new { nameLength = animalName.Length, animalName})
        .Where(x=>x.nameLength > 3)
        .OrderBy(x=>x.nameLength)
        .Select(x=>x.animalName);
240
Marc Gravell

Il y a un bon article ici

Essentiellement, let crée un tuple anonyme. C'est équivalent à:

var result = names.Select(
  animal => new { animal = animal, nameLength = animal.Length })
.Where(x => x.nameLength > 3)
.OrderBy(y => y.nameLength)
.Select(z => z.animal);
85
Keltex

Il existe également une méthode d'extension .Let dans System.Interactive, mais son objectif est d'introduire une expression lambda à évaluer 'en ligne' dans une expression courante. Par exemple, considérons (dans LinqPad, par exemple) l'expression suivante qui crée de nouveaux nombres aléatoires chaque fois qu'elle est exécutée:

var seq = EnumerableEx.Generate(
    new Random(),
    _ => true,
    _ => _,
    x => x.Next());

Pour voir que de nouveaux échantillons aléatoires apparaissent à chaque fois, considérez ce qui suit

seq.Zip(seq, Tuple.Create).Take(3).Dump();

qui produit des paires dans lesquelles la gauche et la droite sont différentes. Pour créer des paires dans lesquelles les côtés gauche et droit sont toujours identiques, procédez comme suit:

seq.Take(3).ToList().Let(xs => xs.Zip(xs, Tuple.Create)).Dump(); 

Si nous pouvions invoquer directement les expressions lambda, nous pourrions écrire

(xs => xs.Zip(xs, Tuple.Create))(seq.Take(3).ToList()).Dump();

Mais nous ne pouvons pas invoquer les expressions lambda comme s'il s'agissait de méthodes.

6
Reb.Cabin

about Code équivalent au mot clé 'let' dans les appels de méthode d'extension LINQ chaînés

le commentaire ci-dessus n'est plus valable

var x = new List<int> { 2, 3, 4, 5, 6 }.AsQueryable();
(from val in x
let val1 = val
let val2 = val + 1
where val2 > val1
select val
).Dump();

produit

System.Collections.Generic.List`1[System.Int32]
.Select(
  val =>
     new
     {
         val = val,
         val1 = val
     }
)
.Select(
  temp0 =>
     new
     {
         temp0 = temp0,
         val2 = (temp0.val + 1)
     }
)
.Where(temp1 => (temp1.val2 > temp1.temp0.val1))
.Select(temp1 => temp1.temp0.val)

donc plusieurs let sont optimisés maintenant

0
Fabio Angela