我有这个结构:
struct Map { public int Size; public Map ( int size ) { this.Size = size; } public override string ToString ( ) { return String.Format ( "Size: {0}", this.Size ); } }
使用数组时,它可以工作:
Map [ ] arr = new Map [ 4 ] { new Map(10), new Map(20), new Map(30), new Map(40)}; arr [ 2 ].Size = 0;
但是当使用List时,它不会编译:
List
为什么?
C#编译器会给你以下错误:
无法修改'System.Collections.Generic.List.this [int]'的返回值,因为它不是变量
原因是结构是值类型,因此当您访问列表元素时,您实际上将访问由列表的索引器返回的元素的中间副本.
来自MSDN:
错误信息
无法修改'expression'的返回值,因为它不是变量
尝试修改作为中间表达式结果的值类型.由于该值未持久存在,因此该值将保持不变.
要解决此错误,请将表达式的结果存储在中间值中,或使用中间表达式的引用类型.
解决方案:
使用数组.这使您可以直接访问元素(您不访问副本)
当您创建Map类时,您仍然可以使用List来存储元素.然后,您将获得对Map对象的引用而不是中间副本,您将能够修改该对象.
如果无法将Map从struct更改为类,则必须将列表项保存在临时变量中:
Listlist = new List () { new Map(10), new Map(20), new Map(30), new Map(40) }; Map map = list[2]; map.Size = 42; list[2] = map;
因为它是a struct
,当使用List
使用结构时,最好使它们不可变.这样可以避免这种效果.
使用数组时,您可以直接访问内存结构.使用List
如果它是一个类,你会得到一个指向该类的指针的副本,但你不会注意到这一点,因为指针隐藏在C#中.
同样使用List
这不是你在使用结构时获得这样效果的唯一地方.
Divo提供的解决方案是一个非常好的解决方法.但是你必须记住以这种方式工作,不仅在使用List