在是否可以从列表中访问结构的引用以进行更改之后,我脑海中提出的问题?reza的线程。
因此,请考虑以下struct
和interface
(绝对不是很有用,而只是为了说明问题):
public interface IChangeStruct
{
int Value { get; }
void Change(int value);
}
public struct MyStruct : IChangeStruct
{
int value;
public MyStruct(int _value)
{
value = _value;
}
public int Value
{
get
{
return value;
}
}
public void Change(int value)
{
this.value = value;
}
}
MyStruct
implements IChangeStruct
,因此我们可以直接在堆中更改它的盒装副本,而无需拆箱并替换为新的。这可以用下面的代码来演示:
MyStruct[] l1 = new MyStruct[]
{
new MyStruct(0)
};
Console.WriteLine(l1[0].Value); //0
l1[0].Change(10);
Console.WriteLine(l1[0].Value); //10
现在,让我们将数组更改为List<T>
,即:
List<MyStruct> l2 = new List<MyStruct>
{
new MyStruct(0)
};
Console.WriteLine(l2[0].Value); //0
l2[0].Change(10);
Console.WriteLine(l2[0].Value); //also 0
据我了解,在第一种情况下l1[0]
,将引用返回到盒装结构,而在第二种情况下 - 它是其他的。
我也试着拆开这个,发现:
1) 对于MyStruct[]
:
IL_0030: ldelema Utils.MyStruct IL_0035: ldc.i4.s 10 IL_0037: call instance void Utils.MyStruct::Change(int32)
2) 对于List<MyStruct>
:
IL_007c: callvirt instance !0 class [mscorlib]System.Collections.Generic.List`1<valuetype Utils.MyStruct>::get_Item(int32)
IL_0081: stloc.s CS$0$0001
IL_0083: ldloca.s CS$0$0001
IL_0085: ldc.i4.s 10
IL_0087: call instance void Utils.MyStruct::Change(int32)
但我似乎还没有准备好解释它。
那么,List<T>
回报是什么呢?或者如何List<T>
按索引排列和返回元素?或者这只是值类型的情况,与引用类型无关?
PS:我确实知道不能更改值类型实例,但是所描述的问题让我明白了,我从来没有意识到List<T>
数组是如何工作的。