2010-11-05 83 views
3

是否有任何指示返回类的对象?我有有一个列表和一个方法,做一些与列表,并返回该列表中的类:C#返回私人对象

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

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

} 

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

你如何处理这种情况?你做了一个对象的副本(在本例中是列表)并返回该对象,或..?有没有最佳做法或窍门?

+0

你相信你的来电者做“正确的事”,如果不是在写一个类的成本变得更多。因此,框架代码花费更多的时间来编写应用程序代码。 – 2010-11-05 10:25:59

回答

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

但请注意,类本身仍然可以修改集合,导致只读集合被修改,使其不适合在多线程应用程序中使用。 – SoftMemes 2010-11-05 09:58:00

+0

@freed这就是为什么我不喜欢'ReadOnlyCollection ' – 2010-11-05 09:58:52

+2

线程安全还有很多,比如线程安全设计,或者根本就没有这样做,开销并不值得“更线程安全” – 2010-11-05 10:05:54

2

为了更好的线程安全,返回它(不过,如果这是一个要求,你应该设计类为与开始)之前进行复制的元素无法修改,请使用ReadOnlyCollection来传达此意图。

或者,您可以实例化新列表并返回新列表中的元素。然后,你的班级不必关心该列表是否被修改。

0

怎么样

return new List<Bar>(_myList); 

将这项工作? 对不起 - 太慢;)

1

真正的问题不是关于你的私人_myList的副本,而是将是:你的手还有一些项目的副本?

返回列表的副本,你有几种选择

  • ReadOnlyCollection<T>
  • IEnumerable<T>(propably一个真正的转换,否则攻击者可以投回到List<T>在外面)
  • 一通过.ToList()
  • 拨打List<T>与私人清单的电话

我不是ReadOnlyCollection<T>的粉丝,因为它只是剥夺了消费者添加和删除内容的能力,但与私人列表的连接并未被切断。所以当你改变你的私人清单时,它会影响那些无用的只读集合...这可能是一件坏事!

我建议选择一个选项,其中返回值完全隔离您的内部列表和项目!

+0

“.ToList()”或“List '的构造函数的用法有任何区别吗? – Martijn 2010-11-05 10:08:31

+0

dunno ...你将不得不测试它与秒表...其实从来没有想过... – 2010-11-05 10:11:23

+0

我刚刚经历,构造函数版本保持参考。当我做'Collection newList = new Collection (_myList);'然后添加一个对象到newList,_myList也会被更新。这怎么可能? – Martijn 2010-11-05 10:49:45