是否有任何指南可以返回类的对象?我有一个类,它有一个List和一个方法,它对列表做了一些事情并返回该列表:
public class Foo
{
private List<Bar> _myList = new List<Bar>();
public List<Bar> DoSomething()
{
// Add items to the list
return _myList;
}
}
我不认为这是返回列表的好方法,因为现在调用方法可以修改列表,从而更新对象Foo中的列表。这可能会导致意外和不受欢迎的行为。
你如何处理这种情况?您是否复制了对象(在本例中为列表)并返回该对象,或者?有没有最佳做法或技巧?
答案 0 :(得分:7)
返回新的ReadOnlyCollection
:
public ReadOnlyCollection<Bar> DoSomething()
{
// Add items to the list
return new ReadOnlyCollection<Bar>(_myList);
}
这是列表的包装器,类型显式是只读类型。
正如@Freed所说,这不是线程安全的,因为它只是一个包装器,列表可以在Foo
类中更改。
为了更好的线程安全性,请在返回之前复制一份(尽管如果这是一个要求,你应该为它开始设计类):
public ReadOnlyCollection<Bar> DoSomething()
{
// Add items to the list
return new ReadOnlyCollection<Bar>(new List<Bar>(_myList));
}
答案 1 :(得分:2)
如果要确保无法修改元素集合,请使用ReadOnlyCollection
来传达此意图。
或者,您可以实例化一个新列表并返回该新列表中的元素。然后,您的班级不必关心该列表是否被修改。
答案 2 :(得分:1)
真正的问题不在于您的私人_myList
的副本,而是它是:您是否也分发了这些项目的副本?
要返回列表副本,您有几个选项
ReadOnlyCollection<T>
IEnumerable<T>
(可能是真正的转换,否则攻击者可以回到外面的List<T>
).ToList()
List<T>
的ctor 我不是ReadOnlyCollection<T>
的粉丝,因为它只是剥夺了消费者添加和删除内容的能力,但是与私人列表的连接并没有被删除。所以当你改变你的私人名单时,它会影响那些笨拙的readonly-collection ......这可能是一件坏事!
我建议选择一个选项,其中返回值与内部列表和项目完全隔离!
答案 3 :(得分:0)
怎么样
return new List<Bar>(_myList);
那会有用吗?
抱歉 - 太慢了;)
答案 4 :(得分:0)
您可能需要考虑ReadOnlyCollection<T>
- 请参阅Best practice when returning an array of values (.NET)
答案 5 :(得分:0)
您可以使用AsReadOnly扩展程序