gk.*_*gk. 12 .net c# generics ienumerable
为什么列表list1Instance和下面代码p的Main方法指向同一个集合?
class Person
{
public string FirstName = string.Empty;
public string LastName = string.Empty;
public Person(string firstName, string lastName) {
this.FirstName = firstName;
this.LastName = lastName;
}
}
class List1
{
public List<Person> l1 = new List<Person>();
public List1()
{
l1.Add(new Person("f1","l1"));
l1.Add(new Person("f2", "l2"));
l1.Add(new Person("f3", "l3"));
l1.Add(new Person("f4", "l4"));
l1.Add(new Person("f5", "l5"));
}
public IEnumerable<Person> Get()
{
foreach (Person p in l1)
{
yield return p;
}
//return l1.AsReadOnly();
}
}
class Program
{
static void Main(string[] args)
{
List1 list1Instance = new List1();
List<Person> p = new List<Person>(list1Instance.Get());
UpdatePersons(p);
bool sameFirstName = (list1Instance.l1[0].FirstName == p[0].FirstName);
}
private static void UpdatePersons(List<Person> list)
{
list[0].FirstName = "uf1";
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以改变这种行为而不改变返回类型List1.Get()吗?
谢谢
Meh*_*ari 34
事实上,IEnumerable<T> 已经是readonly.这意味着您不能用不同的项替换基础集合中的任何项.也就是说,您无法更改对集合中保留的对象的引用Person.Person但是,该类型不是只读的,因为它是引用类型(即a class),您可以通过引用更改其成员.
有两种解决方案:
struct作为返回类型(每次返回时都会生成值的副本,因此原始值不会被更改 - 顺便说一下,这可能代价很高)Person类型上使用只读属性来完成此任务.在Get()中返回一个Person的新实例,p而不是p它自己的副本.您需要一个方法来制作Person对象的深层副本来执行此操作.这不会使它们只读,但它们将与原始列表中的不同.
public IEnumerable<Person> Get()
{
foreach (Person p in l1)
{
yield return p.Clone();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11770 次 |
| 最近记录: |