我有一些遗留的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;
}
答案 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
它现在包含元素1
,2
和3
。< / 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)公开原始列表mList
。 Add()
或AddRange()
或Clear()
会影响(修改)它
(2)如果null
为空,则返回mList
!