在调用 Int32 上的方法时发出 IL NullReferenceException



我是 .NET 中 IL 的新手,并且正在尝试自动生成纯样板方法。

我的测试应用程序生成以下 IL,但它在已知不是 NULL 的实例上检索int属性的值后,在IL_002f处抛出 NullReferenceException(通过 IL (IL_0001( 和我生成的测试用例(。实例在第一个参数(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 是您的选择(:

.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()

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

出于这个原因,正如评论中所建议的,最好的方法是研究文档并向一位非常特殊的老师学习:编译器。首先使用受支持的语言编写代码,并了解编译器如何转换为 IL。

相关内容

  • 没有找到相关文章

最新更新