こんにちは、奇妙な動作を生成する次のコードがあります。linq to Objects によって生成された IEnumerable に含まれるオブジェクトのインスタンスのプロパティは、後続の foreach ステートメントで更新されません。foreach ステートメントは、IEnumerable を列挙する必要があります。代わりに、解決策は前に列挙することです。
私は解決策を見つけましたが、同様の例を扱っている本や記事のどこにもこれが文書化されているのを見たことがありません。おそらく、linq の複雑な知識を持つ誰かがそれを説明できるでしょう。
エラーの正確な原因を特定するのに 1 日かかりました。大規模なアプリケーションでデバッグするのは簡単ではありません。次に、以下に示す、はるかに単純な環境でそれを再現しました。
public class MyClass
{
public int val ;
}
public class MyClassExtrax
{
public MyClass v1 { get; set; }
public int prop1 { get; set; }
}
void Main()
{
List <MyClass> list1 = new List<MyClass>();
MyClass obj1 = new MyClass(); obj1.val = 10;
list1.Add(obj1);
MyClass obj2 = new MyClass();
obj2.val = 10;
list1.Add(obj2);
IEnumerable<MyClassExtrax> query1 =
from v in list1
where v.val >= 0
select new MyClassExtrax{ v1=v , prop1=0 } ;
//query1=query1.ToList(); solves the problem..but why is this needed..?
foreach (MyClassExtrax fj in query1)
{
fj.v1.val = 40;
fj.prop1 = 40; //property does not get updated..
}
foreach (MyClass obj in list1)
{
Console.WriteLine("in list 1 value is {0} : ", obj.val);
}
foreach (MyClassExtrax obj in query1)
{
Console.WriteLine("in MyClassExtra list v1.val is {0}, prop1 is {1} ", obj.v1.val, obj.prop1);
}
}
出力: リスト 1 の値は 40 です:
リスト 1 の値は 40 です。
MyClassExtra リストの v1.val は 40、prop1 は 0
MyClassExtra リストの v1.val は 40、prop1 は 0
ご覧のとおり、prop1 は 40 に更新されません。