【问题标题】:How to return a readonly copy of a collection如何返回集合的只读副本
【发布时间】:2009-05-12 17:29:31
【问题描述】:

我有一个包含集合的类。我想提供一个返回集合内容的方法或属性。如果调用类可以修改单个对象是可以的,但我不希望它们从实际集合中添加或删除对象。我一直在将所有对象复制到一个新列表中,但现在我想我可以将列表返回为 IEnumerable。

在下面的简化示例中,GetListC 是返回集合的只读版本的最佳方式吗?

public class MyClass
{
    private List<string> mylist;

    public MyClass()
    {
        mylist = new List<string>();
    }

    public void Add(string toAdd)
    {
        mylist.Add(toAdd);
    }

    //Returns the list directly 
    public List<String> GetListA 
    { 
        get
            {
            return mylist;
            }
    }

    //returns a copy of the list
    public List<String> GetListB
    {
        get
        {
            List<string> returnList = new List<string>();

            foreach (string st in this.mylist)
            {
                returnList.Add(st);
            }
            return returnList;
        }
    }

    //Returns the list as IEnumerable
    public IEnumerable<string> GetListC
    {
        get 
        {
            return this.mylist.AsEnumerable<String>();
        }

    }

}

【问题讨论】:

    标签: c# collections properties readonly


    【解决方案1】:

    你可以使用List(T).AsReadOnly():

    return this.mylist.AsReadOnly()
    

    这将返回一个ReadOnlyCollection

    【讨论】:

    • 它在 System.Collections.ObjectModel 命名空间中。
    • 嗯,我很惊讶我弄乱了那个。
    • 当然,您需要将返回类型从 List 替换为 ReadOnlyCollection 或 ICollection 或 IEnumrable
    【解决方案2】:

    只需使用 ReadOnlyCollection 类,从 .NET 2.0 开始就支持它

    【讨论】:

      【解决方案3】:

      使用通用的 ReadOnlyCollection 类 (Collection.AsReadOnly())。它不会复制任何在底层集合更改时可能会产生一些奇怪结果的对象。

              var foo = new List<int> { 3, 1, 2 };
              var bar = foo.AsReadOnly();
      
              foreach (var x in bar) Console.WriteLine(x);
      
              foo.Sort();
      
              foreach (var x in bar) Console.WriteLine(x);
      

      但如果您不想要副本,那是最好的解决方案。

      【讨论】:

        【解决方案4】:

        我更喜欢返回 IEnumerable,但您不需要强制转换。做吧

        public IEnumerable<string> StringList { get { return myList; }
        

        List&lt;string&gt;IEnumerable&lt;string&gt;

        【讨论】:

        • 这样做的问题是确定计数之类的事情变得非常昂贵。
        • 真正的问题是代码的使用者可以随时将其转换回 List 并修改列表。
        • 你并不总是需要计数,关键是要公开一个接口,它可以提供你需要的所有功能,而你不需要
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-13
        • 1970-01-01
        • 2021-01-19
        相关资源
        最近更新 更多