AddRange 授予 public 访问列表的权限

AddRange in give public access to list

我有一些遗留的 C# 代码,其中包含以下部分:

private List<MyClass> mList = new List<MyClass>();

public List<MyClass> getList()
{
   List<MyClass> list = new List<MyClass>();
   list.AddRange(mList);
   return list;
}

不确定这里 AddRange 的目的是什么?我可以将其重写为:

public List<MyClass> getList()
{
   return mList;
}

没有

如果您只是使用 return mlist,您 return 是 mlist 实例,而原始代码 return 是它的浅拷贝。


说你的 class 看起来像这样:

class Foo
{
    public Foo()
    {
        mList.Add(1);
    }

    private List<int> mList = new List<int>();

    public List<int> getList()
    {
        List<int> list = new List<int>();
        list.AddRange(mList);
        return list;
    }
}

现在你运行

var x = new Foo();
x.getList().Add(2);
x.getList().Add(3);

mList 的内容仍将是单个 1,因为调用 getList return 编辑了 mList 的副本,而不是列表本身。

如果像您在问题中所做的那样更改代码,您将更改 mList 它现在将包含元素 123 .


从方法名称中不清楚副本是 returned,因此您可能想将其更改为 GetListCopy 之类的名称(在这种情况下,该方法可以简单地 return new List<MyClass>(mList)mList.ToList()),或 return 列表作为 IReadOnlyList 以明确列表不应更改。

public IReadOnlyCollection<MyClass> getList()
{
    return mList.AsReadOnly();
}

不,你不能。 这可能会导致您的软件出现一些意外行为,因为代码会创建一个新的 List 实例,而您的解决方案在每次调用该方法时都会返回相同的实例。

如前所述,如果您只使用 return mList;,它将 return 原始列表而不是它的副本。

但是您可以使用 :

来简化它
public List<MyClass> getList
{
   return mList.ToList();  // returns copy of original list
}

这里的唯一目的是克隆原始列表以保持其不变。 但是,最好重写这个 属性 并把它变成方法:

public List<MyClass> getList()
{
   // note, that Enumerable.ToList() does the same
   return new List(mList);
}

List<T> 构造函数检查源 IEnumerable<T> 中的 ICollection<T> 实现,并正确设置初始容量。由于每次调用都会创建新实例,因此这不应该是一个 属性,而是一个方法。

Tim 和 Sloth 的评论已经给出了正确的解释。

补充一点:

private List<MyClass> mList = new List<MyClass>();

public List<MyClass> getList1()
{
    List<MyClass> list = new List<MyClass>();
    list.AddRange(mList);
    return list;
}

public List<MyClass> getList2()
{
    return mList;
}

getlis1() -
(1) 保持原始列表安全Add()AddRange()Clear() 不影响它。
(2) 如果 mList 为空, 抛出 异常!

getlis2() -
(1) 公开原始列表 mListAdd()AddRange()Clear() 影响(修改)它。
(2) Returns null 如果 mList 为空!