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
キーワードを使用すると、animalName.Length
を重複して呼び出すことなく、値をwhereおよびorderby操作に転送できます。
ここで「let」キーワードの機能を実現する、LINQ拡張メソッド呼び出しの同等のセットは何ですか?
Letには独自の操作はありません。 Select
から便乗します。 「reflector」を使用して既存のdllを分解すると、これを確認できます。
何かのようになります:
var result = names
.Select(animalName => new { nameLength = animalName.Length, animalName})
.Where(x=>x.nameLength > 3)
.OrderBy(x=>x.nameLength)
.Select(x=>x.animalName);
良い記事があります こちら
基本的に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);
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();
しかし、ラムダ式をメソッドのように呼び出すことはできません。
about 連鎖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
が最適化されました