En utilisant les fonctionnalités de compréhension des requêtes des compilateurs C #, vous pouvez écrire du code comme:
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 let
mot - clé permet à une valeur d'être transmise aux opérations where et orderby sans appels dupliqués à animalName.Length
.
Quel est l'ensemble équivalent d'appels de méthode d'extension LINQ qui réalise ce que le mot-clé "let" fait ici?
c#
linq
extension-methods
linq-to-objects
LBushkin
la source
la source
Réponses:
Let n'a pas sa propre opération; il se chevauche
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);
la source
.Dump()
méthode d'extension dans LinqPad pour voir le lambda résultant.Il y a un bon article ici
Crée essentiellement
let
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);
la source
it seems prudent to recommend against using the let keyword in cases where you do not need to transform a variable
This could be considered a micro-optimisation
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 fluide. 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();
ce qui produit des paires dans lesquelles la gauche et la droite sont différentes. Pour produire des paires dans lesquelles la gauche et la droite sont toujours les mêmes, procédez comme suit:
seq.Take(3).ToList().Let(xs => xs.Zip(xs, Tuple.Create)).Dump();
Si nous pouvions invoquer directement des expressions lambda, nous pourrions écrire
(xs => xs.Zip(xs, Tuple.Create))(seq.Take(3).ToList()).Dump();
Mais nous ne pouvons pas invoquer des expressions lambda comme s'il s'agissait de méthodes.
la source
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 valide
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 maintenantla source