2015-11-07 23 views
0

我碰到過這個答案,說明它不能做,但我想知道爲什麼爲什麼不能更新IEnumerable <>中的元素的屬性?

Updating an item property within IEnumerable but the property doesn't stay set?

拿這個代碼,例如:

var MyClasses = new[] { 1, 2, 3, 4 }.Select(id => new MyClass { Id = id }); 

MyClass BobClass = MyClasses.FirstOrDefault(_mc => _mc.Id == 3); 

BobClass.FirstName = "Bob"; 

Console.WriteLine("Id: {0}, FirstName: {1}", BobClass.Id, BobClass.FirstName); 

foreach (var MyClass in MyClasses) 
{ 
    Console.WriteLine("Id: {0}, FirstName: {1}", MyClass.Id, MyClass.FirstName); 
} 
  • 我創建一個集合。
  • 我使用FirstOrDefault()從集合中獲得Id == 3的元素。這讓我參考了集合中的元素。
  • 我將其FirstName屬性設置爲Bob
  • 當我遍歷列表時,FirstName仍爲null。

我不明白這是如何工作的。我清楚地得到了原始對象的引用,但它幾乎就好像FirstOrDefault()給我的是對象的副本而不是引用。我可以更新副本,但顯然不會保留原文,因爲它們是兩個完全獨立的實體。

更新

哇,這是有趣:

BobClass = MyClasses.FirstOrDefault(mc => object.ReferenceEquals(BobClass, mc)); 

鮑勃返回null ...?總得說...我在這裏肯定很難受。

回答

1

MyClasses是一個IEnumerable。這將在您每次訪問時執行。這本身並不能更新其中的一個類。但是...每次創建MyClass的新實例。這些顯然會有未初始化的屬性。如果添加.ToList(),您將獲得您期望的行爲。

+0

DUH ...他們沒有實例化,直到迭代器開始,所以我每次開始使用迭代器時創建新的對象。謝謝。 – oscilatingcretin

+0

當您開始將匿名代理視爲lambda時,這很有意義。新的MyClass()表達式存在於尚未被調用的委託中,所以當委託被調用時,它將在每次迭代時執行新的MyClass()。 – oscilatingcretin

相關問題