为了更懒惰,我只想写更少的代码但做同样的事情,所以我做了一个测试。只想使用一些属性并使用mono.cecil将.dll文件注入一些il代码。以下是详细信息: 编码时:
[FillProperty("Counter")]
public int Counter
{
get;
set;
}
注入后,生成新代码(通过ILSpy)(C#代码):
public int Counter
{
[CompilerGenerated]
get
{
return this.<Counter>k__BackingField;
}
[CompilerGenerated]
set
{
if (this.<Counter>k__BackingField != value)
{
this.<Counter>k__BackingField = value;
this.<Counter>k__BackingField.TriggerEvent("Counter");
}
}
}
定义代码:
`private int <Counter>k__BackingField;`
无法看到,但IL代码很好:
IL_0000: ldarg.0
IL_0001: ldfld int32 AssemblyTest::'<Counter>k__BackingField'
IL_0006: ldarg.1
IL_0007: beq IL_0023
IL_000c: ldarg.0
IL_000d: ldarg.1
IL_000e: stfld int32 AssemblyTest::'<Counter>k__BackingField'
IL_0013: ldarg.0
IL_0014: ldfld int32 AssemblyTest::'<Counter>k__BackingField'
IL_0019: ldstr "Counter"
IL_001e: callvirt void ['Assembly-CSharp']ExMethod::TriggerEvent<int32>(!!0, string)
IL_0023: ret
定义代码也很好:
.field private int32 '<Counter>k__BackingField'
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
但是当我运行注入的代码时,它会抛出一个异常:“NullReferenceException:对象引用未设置为对象AssemblyTest.set_Counter(Int32 value)的实例”。那么有谁可以给我一些提示。
答案 0 :(得分:0)
方法void ['Assembly-CSharp']ExMethod::TriggerEvent<int32>(!!0, string)
是一种扩展方法,因此它是static
。使用OpCodes.Call
调用静态方法。将Callvirt
切换为Call
,它应该可以解决您的问题。