2011-01-13 34 views
9

名單上有一些類List - 特性:只讀在C#

class Foo { 
    private List<int> myList; 
} 

我只想讀提供進入這一領域。

I.e.我希望屬性可以訪問Enumerable,Count等,並且不需要清除,添加,刪除等。我該怎麼做?

+0

我要去頭並更改標題這個問題只讀,因爲只讀和不變性是兩個非常不同的相關主題,如果我們不混合它們,我更喜歡它。如果你正在尋找不變性檢查http://stackoverflow.com/a/9009748/58961。 –

回答

25

如果你想要列表的只讀視圖,你可以使用ReadOnlyCollection<T>

class Foo { 
    private ReadOnlyCollection<int> myList; 
} 
+3

或者更準確地說,一個私有'List '變量和一個公共'ReadOnlyCollection '屬性,它帶有返回變量的'get {}'。 –

+3

@Victor:通過簡單的演員就可以調用代碼訪問可變列表。可能不是OP想要的。 readonly屬性可以返回新的ReadOnlyCollection (myList);'雖然。 –

+8

ReadOnlyCollection並不是真正的不可變的,因爲它包含一個指向原始列表的指針 - 如果你添加了一些東西到你的列表中,readOnly-instance可以訪問這個新的項目......但是,你說得對,當涉及到修改時 - 方法 - 這些都沒有了! –

0

如果聲明在類的只讀列表中,您仍然可以添加項目到它。

如果您不想添加或更改任何內容,您應該按照Darin的建議使用ReadOnlyCollection<T>

如果要添加,從列表中刪除項目但不想更改內容,可以使用readonly List<T>

9

我會去

public sealed class Foo 
{ 
    private readonly List<object> _items = new List<object>(); 

    public IEnumerable<object> Items 
    { 
     get 
     { 
      foreach (var item in this._items) 
      { 
       yield return item; 
      } 
     } 
    } 
} 
+4

爲什麼在最後的收益率突破呢? –

+0

另外Foo可以實現IEnumerable – Turowicz

+0

@Jon Skeet:只是複製過去......起初我有一個'// TODO',但用foreach替換它......感謝那個提示! –

8

可以暴露List<T>ReadOnlyCollection<T>使用方法AsReadOnly()

class Foo { 

    private List<int> myList; 

    public ReadOnlyCollection<int> ReadOnlyList { 
    get { 
     myList.AsReadOnly(); 
    } 
    } 
} 

整潔的事情是,如果你添加/從您的私人列表中刪除任何東西它也反映在返回的ReadOnlyCollection中

+0

尼斯和乾淨,正是我想要的。 – AnthonyVO

5

現在有一個不可變的集合庫來完成這個工作。你可以通過nuget安裝。

的不可變集合類開始支持在.NET框架 4.5。

https://msdn.microsoft.com/en-us/library/dn385366%28v=vs.110%29.aspx

的System.Collections.Immutable命名空間提供,您可以使用這些方案的通用不可改變 集合類型,包括: ImmutableArray <牛逼>, ImmutableDictionary < TKEY,TValue >, ImmutableSortedDictionary <T>,ImmutableHashSet <T>, ImmutableList <牛逼>,ImmutableQueue <牛逼>,ImmutableSortedSet <牛逼>, ImmutableStack <牛逼>

使用示例:

class Foo 
{ 
    public ImmutableList<int> myList { get; private set; } 

    public Foo(IEnumerable<int> list) 
    { 
     myList = list.ToImmutableList(); 
    } 
}