我有一个具有泛型类型的私有变量的类。
在类中我已经声明了一个Foo方法。
检查IL后,我发现方法Push的目标实际上是方法调用set_Property2,而不是类的字段。
编译器如何在两者之间建立连接?有关字段参考的MSIL问题
public class A
{
public int Property1 { get; set; }
public int Property2 { get; set; }
}
public class ShortDemo
{
private Stack<A> _stack = new Stack<A>();
private void Foo()
{
_stack.Push(new A()
{
Property1 = 1,
Property2 = 2
});
}
}
而IL:
.method private hidebysig instance void Foo() cil managed
{
.maxstack 3
.locals init (
[0] class ConsoleApplication1.A g__initLocal0)
L_0000: nop
L_0001: ldarg.0
L_0002: ldfld class [System]System.Collections.Generic.Stack1 ConsoleApplication1.ShortDemo::_stack
L_0007: newobj instance void ConsoleApplication1.A::.ctor()
L_000c: stloc.0
L_000d: ldloc.0
L_000e: ldc.i4.1
L_000f: callvirt instance void ConsoleApplication1.A::set_Property1(int32)
L_0014: nop
L_0015: ldloc.0
L_0016: ldc.i4.2
L_0017: callvirt instance void ConsoleApplication1.A::set_Property2(int32)
L_001c: nop
L_001d: ldloc.0
L_001e: callvirt instance void [System]System.Collections.Generic.Stack1::Push(!0)
L_0023: nop
L_0024: ret
}
您的字段在L_0024加载,然后将方法的参数放在堆栈上,然后在L_0052处调用Push。问题是什么? – kvb 2010-10-29 17:12:28
这里有太多的事情要做,以便于分析。请提供一个简短但完整的程序来证明这一点,尽可能使用简短的方法。 – 2010-11-05 15:54:27
我注意到它仅在使用对象初始值设定项时发生。当我创建A的新实例并将其推入堆栈时,ldfld行将从L_0002中省略并插入L_001a,这对我来说很有意义。 – Sagi 2010-11-05 16:37:39