C# 如何制作列表';在使用get属性公开列表时,是否添加受保护的方法?

C# 如何制作列表';在使用get属性公开列表时,是否添加受保护的方法?,c#,list,properties,C#,List,Properties,我有一个名为WhatClass的类,其中包含列表字段。我需要能够只读此字段,因此我使用get属性将其公开给其他对象 public class WhatClass { List<SomeOtherClass> _SomeOtherClassItems; public List<SomeOtherClass> SomeOtherClassItems { get { return _SomeOtherClassItems; } } } 如何防止这种情况发生?

我有一个名为WhatClass的类,其中包含列表字段。我需要能够只读此字段,因此我使用get属性将其公开给其他对象

public class WhatClass
{
    List<SomeOtherClass> _SomeOtherClassItems;

    public List<SomeOtherClass> SomeOtherClassItems { get { return _SomeOtherClassItems; } }
}

如何防止这种情况发生?

如何使用
AsReadOnly()
?-

使用:

public ReadOnlyCollection SomeOtherClassItems
{
得到
{
返回_SomeOtherClassItems.AsReadOnly();
}
}
这将返回一个,如果客户端通过接口调用Add,则会引发异常。此外,ReadOnlyCollection类型不公开公共Add方法

您正在寻找,它是一个围绕
IList
的只读包装

由于
ReadOnlyCollection
将反映基础列表中的更改,因此不需要每次都创建一个新实例

例如:

public class WhatClass {
    public WhatClass() {
        _SomeOtherClassItems = new List<SomeOtherClass>();
        SomeOtherClassItems = _SomeOtherClassItems.AsReadOnly();
    }

    List<SomeOtherClass> _SomeOtherClassItems;

    public ReadOnlyCollection<SomeOtherClass> SomeOtherClassItems { get; private set; }
}
公共类WhatClass{
公共WhatClass(){
_SomeOtherClassItems=新列表();
SomeOtherClassItems=\u SomeOtherClassItems.AsReadOnly();
}
列出其他一些分类项目;
public ReadOnlyCollection SomeOtherClassItems{get;private set;}
}

正如其他人所说,您正在寻找
.AsReadOnly()
扩展方法

但是,您应该存储对集合的引用,而不是在每次属性访问期间创建它:

private readonly List<SomeOtherClass> _items;

public WhatClass()
{
    _items = new List<SomeOtherClass>();

    this.Items = _items.AsReadOnly();
}

public ReadOnlyCollection<SomeOtherClass> Items { get; private set; }
私有只读列表\u项;
公共WhatClass()
{
_项目=新列表();
this.Items=_Items.AsReadOnly();
}
公共只读集合项{get;private set;}
这是为了确保
x.Items==x.Items
为真,否则API消费者可能会非常意外

公开
ReadOnlyCollection
将您的只读收藏意图传达给消费者。对
\u项的更改将反映在
项中

您只需使用ToList()返回列表的副本即可。其他类可以做他们喜欢的事情来复制它不会改变你原来的列表

你应该以名字表明他们正在得到一份副本

using System.Linq;

public class WhatClass
{
    List<SomeOtherClass> _SomeOtherClassItems;

    public List<SomeOtherClass> SomeOtherClassItems { get { return _SomeOtherClassItems.ToList(); } }
}
使用System.Linq;
公共类WhatClass
{
列出其他一些分类项目;
公共列表SomeOtherClassItems{get{return}
}

尽管其他人指出了使用
ReadOnlyCollection
,但值得注意的是,也存在一个很酷的
ReadOnlyObservableCollection
。它在绑定和视图模型中非常有用。作为:

此类是围绕ObservableCollection的只读包装。如果对基础集合进行了更改,ReadOnlyObservableCollection将反映这些更改。要获得此类更改的通知,请订阅CollectionChanged或PropertyChanged事件


您只需公开此
ReadOnlyObservableCollection
并对基础集合进行更改,并确保您的视图正在更新。

不要每次都创建一个新实例。@SLaks:我明白您的意思,但这是一个微观优化,我相信这样读起来更容易。ReadOnlyCollection很小,GC擅长处理小的短期对象,并且通过添加一个字段和一个ReadOnlyCollection对象,您很可能会使用更多内存,而您的每个类都不需要这些字段和对象。在属性getter中分配对象不是一个好主意。人们通常认为访问属性getter只不过是一次内存读取,因此会在大型嵌套循环中多次访问该属性。@SLaks:没关系,我在Bryan的回答中看到了关于引用相等的论点。我没有考虑过。你可能想为大众详细说明当你添加到_项时会发生什么以及如何处理…@Dave-文档声明更改将反映在包装中。Bryan,非常感谢你的回答,虽然我在这里不需要只读关键字。@Witchunter:您没有在构造函数之后分配
\u项
readonly
关键字传达了以下意图:。如果您计划在构建
WhatClass
之后为
\u items
分配另一个值,则还需要重新分配
items
属性。谢谢您的回答。您提到了ReadOnlyCollection类,但没有将其包含在代码中,但我已经找到了答案。再次感谢你。
private readonly List<SomeOtherClass> _items;

public WhatClass()
{
    _items = new List<SomeOtherClass>();

    this.Items = _items.AsReadOnly();
}

public ReadOnlyCollection<SomeOtherClass> Items { get; private set; }
using System.Linq;

public class WhatClass
{
    List<SomeOtherClass> _SomeOtherClassItems;

    public List<SomeOtherClass> SomeOtherClassItems { get { return _SomeOtherClassItems.ToList(); } }
}