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
它现在将包含元素 1
、2
和 3
.
从方法名称中不清楚副本是 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) 公开原始列表 mList
。 Add()
或 AddRange()
或 Clear()
影响(修改)它。
(2) Returns null
如果 mList
为空!
我有一些遗留的 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
它现在将包含元素 1
、2
和 3
.
从方法名称中不清楚副本是 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) 公开原始列表 mList
。 Add()
或 AddRange()
或 Clear()
影响(修改)它。
(2) Returns null
如果 mList
为空!