以下是返回安全列表枚举器的好方法?

时间:2010-04-21 14:23:39

标签: c#

 public class Foo{
        public string Prop1 {get;set;}
        public string Prop2 {get;set;}

        public Foo(Foo source) {
            this.Prop1 = source.Prop1;
            this.Prop2 = source.Prop2;
        }
    }

    public class Main
    {
        private List<Foo> items = new List<Foo>();

        public IEnumerable<Foo> GetItems() {
            foreach (Foo foo in items) {
                yield return new Foo(foo);
            }
        }
    }

3 个答案:

答案 0 :(得分:1)

这取决于你所说的安全。如果调用对象只是从foo读取信息。而不是:

public IEnumerable<Foo> GetItems() {
            foreach (Foo foo in items) {
                yield return new Foo(foo);
            }

为什么不这样做:

public IEnumerable<Foo> GetItems() {
            foreach (Foo foo in items) {
                yield return foo;
            }

如果您试图阻止调用对象修改原始foo,那么您所做的就会起作用。

您也可以将foo设置为不可变,并且您不必担心确保正确复制所有属性等。这样您每次返回时都不必创建新对象普查员。

eric lippert关于不变性的帖子:
http://blogs.msdn.com/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx

关于不变性的其他联系:
http://codebetter.com/blogs/patricksmacchia/archive/2008/01/13/immutable-types-understand-them-and-use-them.aspx

答案 1 :(得分:0)

免责声明:我了解Java,但对C#的经验很少

如果您正在尝试创建副本列表以使原始列表元素保持“不可变”,并希望尽可能地使其成为一般,那么您可能应该调查克隆,或者更准确地说,deep-copying

否则只是创建Item foo的新实例不一定能确保你有完美的初始化副本吗?

答案 2 :(得分:0)

好的,所以似乎很清楚你正在寻找一个不可变的迭代器。这有效,但效率不高。你可以尝试这样做你的课:

public class Foo {
    public string Prop1 { get; private set;}
    public string Prop2 { get; private set;}

    public Foo(string prop1, string prop2) {
        this.Prop1 = prop1;
        this.Prop2 = prop2;
    }
}

它不是完全不可变的,但对于大多数意图来说都是如此。