Kod odpowiadający słowu kluczowemu 'let' w wywołaniach łańcuchowych metody rozszerzenia LINQ

Używając funkcji kompilatorów C#, możesz napisać kod w stylu:

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 powyższym wyrażeniu zapytania słowo kluczowe let umożliwia przekazanie wartości do operacji where I orderby bez powielania wywołań do animalName.Length.

Jaki jest równoważny zbiór wywołań metody rozszerzenia LINQ, który osiąga to, co robi tutaj słowo kluczowe "let"?

Author: Keltex, 2009-07-07

4 answers

Niech nie ma własnego działania, to nie działa Select. Możesz to zobaczyć, jeśli użyjesz "reflektora", aby rozdzielić istniejącą bibliotekę dll.

To 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);
 258
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-30 07:47:56

Jest tu dobry artykuł

Zasadniczo let tworzy anonimową krotkę. Jest równoważne:

var result = names.Select(
  animal => new { animal = animal, nameLength = animal.Length })
.Where(x => x.nameLength > 3)
.OrderBy(y => y.nameLength)
.Select(z => z.animal);
 89
Author: Keltex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-28 06:09:24

Istnieje również .Niech metoda rozszerzenia w systemie.Interaktywny, ale jego celem jest wprowadzenie wyrażenia lambda, które ma być oceniane "in-line" w wyrażeniu płynnym. Na przykład, rozważmy (w LinqPad, powiedzmy) następujące wyrażenie, które tworzy nowe liczby losowe za każdym razem, gdy jest wykonywane:

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

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

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

, która tworzy pary, w których lewa i prawa są różne. Aby wytworzyć pary, w których lewa i prawa są zawsze takie same, zrób coś takiego:

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

Gdybyśmy mogli wywoływać wyrażenia lambda bezpośrednio, moglibyśmy napisać

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

Ale nie możemy wywoływać wyrażeń lambda tak, jakby były metodami.

 7
Author: Reb.Cabin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-06 18:01:25

O kodzie odpowiadającym słowu kluczowemu 'let' w wywołaniu łańcuchowej metody rozszerzenia LINQ

Powyższy komentarz nie jest już ważny

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();

Produkuje

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)

TAK WIELE {[2] } jest teraz zoptymalizowanych

 1
Author: Not Important,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-21 14:25:50