C#返回私有对象

时间:2010-11-05 09:50:39

标签: c#

是否有任何指南可以返回类的对象?我有一个类,它有一个List和一个方法,它对列表做了一些事情并返回该列表:

public class Foo
{
  private List<Bar> _myList = new List<Bar>();

  public List<Bar> DoSomething()
  {
    // Add items to the list
    return _myList;
  }

}

我不认为这是返回列表的好方法,因为现在调用方法可以修改列表,从而更新对象Foo中的列表。这可能会导致意外和不受欢迎的行为。

你如何处理这种情况?您是否复制了对象(在本例中为列表)并返回该对象,或者?有没有最佳做法或技巧?

6 个答案:

答案 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扩展程序