为什么列表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 Listl1 = new List (); 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 Get() { foreach (Person p in l1) { yield return p; } //return l1.AsReadOnly(); } } class Program { static void Main(string[] args) { List1 list1Instance = new List1(); List p = new List (list1Instance.Get()); UpdatePersons(p); bool sameFirstName = (list1Instance.l1[0].FirstName == p[0].FirstName); } private static void UpdatePersons(List list) { list[0].FirstName = "uf1"; } }
我们可以改变这种行为而不改变返回类型List1.Get()
吗?
谢谢
事实上,IEnumerable
已经是readonly.这意味着您不能用不同的项替换基础集合中的任何项.也就是说,您无法更改对集合中保留的对象的引用Person
.Person
但是,该类型不是只读的,因为它是引用类型(即a class
),您可以通过引用更改其成员.
有两种解决方案:
使用a struct
作为返回类型(每次返回时都会生成值的副本,因此原始值不会被更改 - 顺便说一下,这可能代价很高)
在Person
类型上使用只读属性来完成此任务.
在Get()中返回一个Person的新实例,p
而不是p
它自己的副本.您需要一个方法来制作Person对象的深层副本来执行此操作.这不会使它们只读,但它们将与原始列表中的不同.
public IEnumerableGet() { foreach (Person p in l1) { yield return p.Clone(); } }