C# 如何返回集合的只读副本

C# 如何返回集合的只读副本,c#,collections,properties,readonly,C#,Collections,Properties,Readonly,我有一个包含集合的类。我想提供一个返回集合内容的方法或属性。如果调用类可以修改单个对象,这没关系,但我不希望它们在实际集合中添加或删除对象。我一直在将所有对象复制到一个新列表中,但现在我想我可以将列表作为IEnumerable返回 在下面的简化示例中,GetListC是返回集合只读版本的最佳方法吗 public class MyClass { private List<string> mylist; public MyClass() { my

我有一个包含集合的类。我想提供一个返回集合内容的方法或属性。如果调用类可以修改单个对象,这没关系,但我不希望它们在实际集合中添加或删除对象。我一直在将所有对象复制到一个新列表中,但现在我想我可以将列表作为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>();
        }

    }

}
公共类MyClass
{
私人名单;
公共MyClass()
{
mylist=新列表();
}
公共空添加(字符串添加)
{
mylist.Add(toAdd);
}
//直接返回列表
公共列表GetListA
{ 
得到
{
返回mylist;
}
}
//返回列表的副本
公共列表GetListB
{
得到
{
List returnList=新列表();
foreach(此.mylist中的字符串st)
{
返回列表。添加(st);
}
退货清单;
}
}
//将列表返回为IEnumerable
公共IEnumerable GetListC
{
得到
{
返回此.mylist.AsEnumerable();
}
}
}

只需使用ReadOnlyCollection类,它是受支持的,因为.NET 2.0

您可以使用:


它将返回一个。

使用泛型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);
var foo=新列表{3,1,2};
var bar=foo.AsReadOnly();
foreach(bar中的变量x)控制台。WriteLine(x);
foo.Sort();
foreach(bar中的变量x)控制台。WriteLine(x);

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

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

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

List
是一个
IEnumerable

它位于System.Collections.ObjectModel命名空间中。哈,我很惊讶我弄乱了这个名称空间。当然,您需要将返回类型从List替换为ReadOnlyCollection或icCollection或IEnumRablet。问题是,确定计数之类的事情变得非常昂贵所有的问题是,代码的使用者可以随时将其转换回列表并修改列表。您并不总是需要计数,关键是要公开一个接口,该接口为您提供所有您需要的功能,而没有一个是您不需要的
public IEnumerable<string> StringList { get { return myList; }