Mar*_*zek 7 c# ienumerable list
假设我有IEnumerable<int>使用List<int>字段支持的属性,所以我可以在类中修改集合,但它是以只读方式公开公开的.
public class Foo
{
private List<int> _bar = new List<int>();
public IEnumerable<int> Bar
{
get { return _bar; }
}
}
Run Code Online (Sandbox Code Playgroud)
但是使用这样的代码,您可以轻松地将从属性中检索到的对象转换回List<int>并修改它:
var foo = new Foo();
var bar = (List<int>)foo.Bar;
bar.Add(10);
Run Code Online (Sandbox Code Playgroud)
问题是:什么是最好的(最好的可读性,最容易编写,没有性能损失)避免这种情况的方法?
我可以提出至少4个解决方案,但不是它们是完美的:
foreach并且yield return:
public IEnumerable<int> Bar
{
get
{
foreach (var item in _bar)
yield return item;
}
}
Run Code Online (Sandbox Code Playgroud)
-写作和阅读真的很烦人.
AsReadOnly():
public IEnumerable<int> Bar
{
get { return _bar.AsReadOnly(); }
}
Run Code Online (Sandbox Code Playgroud)
+当有人试图修改返回的集合时+将导致异常
+不创建整个集合的副本.
ToList()
public IEnumerable<int> Bar
{
get { return _bar.ToList(); }
}
Run Code Online (Sandbox Code Playgroud)
+用户仍然可以修改检索到的集合,但它与我们在课堂上修改的集合不同,所以我们不应该在乎.
-创建整个集合的副本,当集合很大时可能会导致问题.
自定义包装类.
public static class MyExtensions
{
private class MyEnumerable<T> : IEnumerable<T>
{
private ICollection<T> _source;
public MyEnumerable(ICollection<T> source)
{
_source = source;
}
public IEnumerator<T> GetEnumerator()
{
return _source.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_source).GetEnumerator();
}
}
public static IEnumerable<T> AsMyEnumerable<T>(this ICollection<T> source)
{
return new MyEnumerable<T>(source);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
public IEnumerable<int> Bar
{
get
{
return _bar.AsMyEnumerable();
}
}
Run Code Online (Sandbox Code Playgroud)
+不需要克隆集合
-当您将它用作LINQ查询源时,某些方法将不会使用ICollection.Count,因为您不公开它.
有没有更好的方法呢?
Ree*_*sey 13
问题是:什么是最好的(最好的可读性,最容易编写,没有性能损失)避免这种情况的方法?
一般来说,我不会试图避免它.我的API的消费者应该使用我公开的类型,如果他们不这样做,任何错误都是他们的错,而不是我的.因此,我并不关心他们是否以这种方式投放数据 - 当我更改内部表示时,他们会获得强制转换异常,这就是他们的问题.
话虽如此,如果存在安全问题,我可能会使用AsReadOnly.这实际上是自我记录的,并没有真正的缺点(除了包装器的小分配,因为没有数据的副本,你确实得到了有意义的修改异常等).与制作自己的自定义包装器相比,没有真正的缺点,自定义包装器意味着需要更多的代码来测试和维护.
一般来说,我个人试图避免无理由地复制.这将ToList()作为一般选择消除.使用迭代器(你的第一个选项)并不是那么糟糕,尽管它并没有真正提供许多优势ReadOnlyCollection<T>.
| 归档时间: |
|
| 查看次数: |
801 次 |
| 最近记录: |