2人の(結果的に)等価なクエリ間の予期しない動作上の相違について、誰かが(私に)予期せぬ動作上の違いを明らかにできることを願っています。
小さなプログラムは、千の言葉の価値があることができますので、ここに行く:今セットの1つを置き換えた後、JoinとSelectManyの動作が異なる
static void Main(string[] args)
{
var l1 = new List<int> { 1, 2, 3 };
var l2 = new List<int> { 2, 3, 4 };
var q1 = // or var q1 = l1.Join(l2, i => i, j => j, (i, j) => i);
from i in l1
join j in l2
on i equals j
select i;
var q2 = //or var q2 = l1.SelectMany(i => l2.Where(j => i == j));
from i in l1
from j in l2
where i == j
select i;
var a1 = q1.ToList(); // 2 and 3, as expected
var a2 = q2.ToList(); // 2 and 3, as expected
l2.Remove(2);
var b1 = q1.ToList(); // only 3, as expected
var b2 = q2.ToList(); // only 3, as expected
// now here goes, lets replace l2 alltogether.
// Afterwards, I expected the same result as q1 delivered...
l2 = new List<int> { 2, 3, 4 };
var c1 = q1.ToList(); // only 3 ? Still using the previous reference to l2 ?
var c2 = q2.ToList(); // 2 and 3, as expected
}
私はそれが内部的に参加し、パフォーマンスを最適化するために、ルックアップクラスを使用し、あまり知識がなくても知っている、私の推測であるとの組み合わせキャプチャされた変数を使用するとこの動作が発生する可能性がありますが、実際にはわかりません:-)
これはJoelが「漏れ抽象」と呼んでいる例ですか?コメントであなたのクエリ拡張を与え
乾杯、 バート
スポットあり、ありがとうJon! –