我多次遇到这个设计问题,从来没有找到杀手解决方案.
我想公开一个在所有者class范围内可编辑的集合,但只能读取其他公共范围.
试验1:
public class MyClass
{
private List<object> _myList = new List<object>();
public IEnumerable<object> MyList { get { return _myList; } }
}
Run Code Online (Sandbox Code Playgroud)
这个问题是外部代码可以将其强制转换回来List并进行编辑,如下所示:
var x = ((List<object>)MyList);
Run Code Online (Sandbox Code Playgroud)
试验2:
public class MyClass
{
private List<object> _myList = new List<object>();
public IEnumerable<object> MyList { get { return _myList.ToList(); } }
}
Run Code Online (Sandbox Code Playgroud)
这样我们就可以防止外部修改,但会造成List多次复制的不必要开销.
试验3:
public class MyClass
{
private List<object> _myList = new List<object>();
private ReadOnlyCollection<object> _roList =
new ReadOnlyCollection<object>(_myList)
public IEnumerable<object> MyList { get { return _roList; } }
}
Run Code Online (Sandbox Code Playgroud)
这是我目前使用的标准解决方案,但ReadOnlyCollection速度慢了约30%:
Debug Trace:
Use normal foreach on the ReadOnlyCollection
Speed(ms): 2520,3203125
Result: 4999999950000000
use<list>.ForEach
Speed(ms): 1446,1796875
Result: 4999999950000000
Use normal foreach on the List
Speed(ms): 1891,2421875
Result: 4999999950000000
Run Code Online (Sandbox Code Playgroud)
这样做有"完美"的方法吗?谢谢.
您是否尝试过返回枚举器?
public class MyClass
{
private List<object> _myList = new List<object>();
public IEnumerable<object> MyList { get { yield return _myList.GetEnumerator(); } }
}
Run Code Online (Sandbox Code Playgroud)
这不会创建副本,只读,并且不能转换回列表.
编辑:这仅适用于收益率返回.这是懒惰的评估,我不知道这是否是一个问题.
您可以使用List<T>.AsReadOnly方法公开列表的薄只读包装器。不会有额外的复制,调用者将立即“看到”方法内对原始数组所做的更改:
public ReadOnlyCollection<object> MyList { get { return _myList.AsReadOnly(); } }
Run Code Online (Sandbox Code Playgroud)