AddRange允许公共访问列表

时间:2015-10-19 09:46:04

标签: c# .net generics properties

我有一些遗留的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;
}

5 个答案:

答案 0 :(得分:5)

没有

如果您只使用return mlist,则会返回mlist实例,而原始代码会返回它的浅表副本。

说你的课看起来像这样:

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的调用会返回mList的副本,而不是列表本身。

如果您按照问题中的方式更改代码,则会更改mList它现在包含元素123。< / p>

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

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

答案 1 :(得分:2)

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

但是您可以使用以下方法简化它:

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

这里唯一的目的是克隆原始列表以保持不变。 但是,最好重新编写此属性并将其转换为方法:

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

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

答案 4 :(得分:0)

蒂姆的评论和斯洛斯已经给出了正确的解释。

还有一点:

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)如果null为空,则返回mList