.net 4.0 调用Int32上的方法时发出的IL NullReferenceException

.net 4.0 调用Int32上的方法时发出的IL NullReferenceException,.net-4.0,cil,reflection.emit,.net 4.0,Cil,Reflection.emit,我对.NET中的IL还不熟悉,正在尝试自动生成一个纯样板的方法 我的测试应用程序生成下面的IL,但在检索实例上已知不为NULL的int属性值后(通过IL(IL\u 0001)和从我生成的测试用例中),它在IL\u 002f处抛出NullReferenceException。实例在第一个参数(arg.0)中传递给发出的方法 我希望BasicClass.IntProperty的值在调用System.Int32.ToString()之前是堆栈上的第一项,那么这里可能出了什么问题?如果能在这件事上帮我摆

我对.NET中的IL还不熟悉,正在尝试自动生成一个纯样板的方法

我的测试应用程序生成下面的IL,但在检索实例上已知不为NULL的
int
属性值后(通过IL(
IL\u 0001
)和从我生成的测试用例中),它在
IL\u 002f
处抛出NullReferenceException。实例在第一个参数(
arg.0
)中传递给发出的方法

我希望
BasicClass.IntProperty
的值在调用
System.Int32.ToString()
之前是堆栈上的第一项,那么这里可能出了什么问题?如果能在这件事上帮我摆脱困境,我将不胜感激

IL_0000: ldarg.0    
IL_0001: brfalse    IL_0045
IL_0006: ldarg.0    
IL_0007: call       System.String get_StringProperty()/QuickSearchTests.Entities.BasicClass
IL_000c: dup        
IL_000d: brfalse    IL_0022
IL_0012: ldarg.1    
IL_0013: call       Boolean ContainsIgnoreNull(System.String, System.String)/MyCompany.MyProduct.Common.Extensions.StringExtensions
IL_0018: brtrue     IL_0047
IL_001d: br         IL_0023
IL_0022: pop        
IL_0023: ldarg.2    
IL_0024: brfalse    IL_0045
IL_0029: ldarg.0    
IL_002a: call       Int32 get_IntProperty()/QuickSearchTests.Entities.BasicClass
IL_002f: call       System.String ToString()/System.Int32
IL_0034: ldarg.1    
IL_0035: call       Boolean ContainsIgnoreNull(System.String, System.String)/MyCompany.MyProduct.Common.Extensions.StringExtensions
IL_003a: brtrue     IL_0047
IL_003f: br         IL_0045
IL_0044: pop        
IL_0045: ldc.i4.0   
IL_0046: ret        
IL_0047: ldc.i4.1   
IL_0048: ret        
以下是
BasicClass

public class BasicClass
{
    public string StringProperty { get; set; }
    public int IntProperty { get; set; }
    internal string InternalStringProperty { get; set; }
}

您正在对一个非对象调用一个方法:需要对整数值进行装箱以使方法调用工作。我会以这种方式修补您的代码(Z是您的选择):

警告一句:直接编写IL是一件特别具有挑战性的事情。您必须知道,一旦您的IL代码按预期工作,您还没有完成,因为您应该使用peverify进行验证。有效的IL不可自动验证


因此,正如评论中所建议的,最好的方法是研究文档并向一位非常特殊的老师学习:编译器。从用支持的语言编写代码开始,学习编译器如何转换为IL。

我建议用c#(或f#,vb.net)编写代码,编译、反编译并获取生成的IL。也许从那里调整或改变它,但这比从零开始摆弄IL要容易得多。实际上,您可以在这里在线执行此操作:正如您在这里看到的,您必须获取对整数的引用才能对其调用ToString()。你是说我需要堆栈上的引用,而不是实际值吗?也许是时候深入研究EMCAYes了,我非常确定您需要获得对结构的引用,以便对其调用方法。
.locals
[Z] int32 temp

    callvirt instance int32 QuickSearchTests.Entities.BasicClass/BasicClass::get_IntProperty()
    stloc.Z
    ldloca.s temp
    call instance string [System.Runtime]System.Int32::ToString()