205

C#コンパイラのクエリ理解機能を使用すると、次のようなコードを記述できます。

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; 

上記のクエリ式では、letキーワードを使用すると、。を重複して呼び出すことなく、whereおよびorderby操作に値を渡すことができますanimalName.Length

ここで「let」キーワードが行うことを実現する、同等のLINQ拡張メソッド呼び出しのセットは何ですか?

4

4 に答える 4

269

Let には独自の操作はありません。それは便乗しSelectます。これは、「リフレクター」を使用して既存の dll を引き離すとわかります。

次のようになります

var result = names
        .Select(animalName => new { nameLength = animalName.Length, animalName})
        .Where(x=>x.nameLength > 3)
        .OrderBy(x=>x.nameLength)
        .Select(x=>x.animalName);
于 2009-07-07T14:46:00.273 に答える
95

ここに良い記事があります

基本的letに匿名のタプルを作成します。これは次と同等です。

var result = names.Select(
  animal => new { animal = animal, nameLength = animal.Length })
.Where(x => x.nameLength > 3)
.OrderBy(y => y.nameLength)
.Select(z => z.animal);
于 2009-07-07T14:39:12.343 に答える
7

System.Interactive にも .Let 拡張メソッドがありますが、その目的は、流暢な式で「インライン」で評価されるラムダ式を導入することです。たとえば、(LinqPad で) 実行されるたびに新しい乱数を作成する次の式を考えてみます。

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

新しいランダム サンプルが毎回表示されることを確認するには、次のことを考慮してください。

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

左右が異なるペアを生成します。左と右が常に同じペアを作成するには、次のようにします。

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

ラムダ式を直接呼び出すことができれば、

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

しかし、メソッドであるかのようにラムダ式を呼び出すことはできません。

于 2011-06-06T18:01:25.493 に答える
1

連鎖した LINQ 拡張メソッド呼び出しの 'let' キーワードに相当するコードについて

上記のコメントはもはや有効ではありません

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

生産する

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)

そのため、複数letが最適化されています

于 2019-06-21T14:25:50.813 に答える