ReadOnlyCollection
是不可變的事實意味着該集合不能被修改,即不能添加或從集合中刪除對象。這並不意味着它包含的對象是不可變的。
This article作者:Eric Lippert,解釋了不同種類的不變性是如何工作的。基本上,ReadOnlyCollection
是一個不可改變的外觀,可以讀取底層集合(_myDataList
),但無法修改它。但是,您仍然可以更改基礎集合,因爲您可以通過執行諸如_myDataList[0] = null
之類的操作來參考_myDataList
。
此外,由ReadOnlyCollection
返回的對象與由_myDataList
返回的對象相同,即this._myDataList.First() == this.MyReadOnlyList.First()
(具有LINQ
)。這意味着如果_myDataList
中的對象是可變的,那麼MyReadOnlyList
中的對象也是可變的。
如果您希望對象不可變,您應該相應地設計它們。例如,你可以使用:代替
public struct Point
{
public Point(int x, int y)
{
this.X = x;
this.Y = y;
}
// In C#6, the "private set;" can be removed
public int X { get; private set; }
public int Y { get; private set; }
}
:
public struct Point
{
public int X { get; set; }
public int Y { get; set; }
}
編輯:在這種情況下,如Ian Goldby指出,無論是結構允許修改集合中的元素的屬性。發生這種情況是因爲結構是值類型,當您訪問元素時,集合會返回該值的副本。如果它是一個類,則只能修改Point
類型的屬性,這意味着將返回對實際對象的引用,而不是其值的副本。
其實,如果在ReadOnlyCollection對象是結構,而不是類,然後他們有效地只讀的集合,因爲訪問一個元素給你一個* boxed *結構。你不能直接修改它(「不能修改拆箱轉換的結果」),如果你將它賦給本地結構變量,你會得到一個副本。 (儘管您仍然可以通過Items屬性修改ReadOnlyCollection。) –
如果集合是泛型並返回類型爲「T」的元素,爲什麼集合返回的值會被裝箱?除此之外,我更新了我的答案,說集合中的結構是有效的,因爲你只能得到它們的值的副本。 –
我懷疑這是框架的優化,以防止剛剛讀取的結構副本。當然,如果你編寫'roList [i] .X = 5',編譯器會抱怨「無法修改拆箱轉換的結果」。如果編譯器沒有這樣做,那麼'x = roList [i] .X'總是需要爲了讀取一個屬性而創建一個完整的結構副本。 –