À 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?
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);
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);
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.
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