2009-07-07 7 views
166

Korzystanie z funkcji zrozumieniem C# kompilatory kwerendy, można napisać kod takich jak:Kod równoważny "Let słów kluczowych w łańcuchu metodę rozszerzenia LINQ zwraca

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; 

w wyrażeniu kwerendy powyżej, słowo let pozwala wartość przekazywać dalej do miejsca i zlecać operacje bez duplikatów połączeń do animalName.Length.

Jaki jest równoważny zestaw wywołań metod rozszerzających LINQ, który pozwala uzyskać tutaj słowo kluczowe "let"?

+11

FYI, specyfikacja C# 3.0 wyjaśnia każdą regułę tłumaczenia ze zrozumieniem zapytań w rozdzierających szczegółach. –

+16

i dla tych, którzy uważają, że specyfikacja jest ciężka, C# w głębi Jona Skeeta również to obejmuje ;-p –

+4

Uwielbiam to, gdy jestem "zastanawiam się, jak słowo kluczowe" let "mapuje metody rozszerzania ... google to, ale wątpię, że moje poszukiwania znajdą coś oprócz śmieci ... SO FTW! " – Will

Odpowiedz

212

Niech nie ma własnej operacji; to piggy-backs off of Select. Możesz to zobaczyć, jeśli używasz "reflektora", aby rozłączyć istniejącą bibliotekę dll.

będzie coś jak:

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

Woah, nie wiedziałem, że można automatycznie zautomatyzować za pomocą nowego operatora w ten sposób. –

+17

Możesz również użyć małego przycisku "lambda" w okienku wyników LinqPad, aby zobaczyć wygenerowany kod *, jeśli * zaczynasz od Queryable.Innymi słowy, jeśli zmienisz pierwszy wiersz na var names = new string [] {"Dog", ...} .AsQueryable(); następnie uruchom wszystko w LinqPad, kliknij mały przycisk lambda, zobaczysz wygenerowany kod praktycznie identyczny z odpowiedzią Marca. –

+1

Potrzebowałem użyć metody rozszerzenia '.Dump()' w LinqPad, aby zobaczyć wynik lambda. – justanotherdev

77

Jest dobry artykuł here

Zasadniczo let tworzy anonimowy krotki. Jest to odpowiednik:

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

Wygląda na to, że blog zniknął. –

+2

Już nie, teraz łącze do archiwum internetowego. – Ziv

+0

Cytuję powyższy artykuł powyżej "wydaje się rozsądne, aby polecić przeciwko użyciu słowa kluczowego let w przypadkach, gdy nie trzeba przekształcać zmiennej" –

5

Istnieje również metoda rozszerzenie .Let w System.Interactive, ale jego celem jest wprowadzenie wyrażenia lambda być oceniana 'in-line' w płynna ekspresja. Na przykład, należy rozważyć (w LINQPad, powiedzmy) następujące wyrażenie, które tworzy nowe numery losowe każdym razem, gdy jest wykonywany:

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

aby zobaczyć, że nowe losowe próbki pojawiają się za każdym razem, należy rozważyć następujące

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

, który wytwarza pary, w których lewa i prawa są różne. Do produkcji pary, w której lewa i prawa są zawsze takie same, czy coś takiego, co następuje:

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

Jeśli moglibyśmy powołać wyrażeń lambda bezpośrednio, możemy napisać

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

ale nie możemy wywołaj wyrażenia lambda, jakby były metodami.

Powiązane problemy