2011-01-13 31 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(); 
    } 
}