Выдано исключение IL NullReferenceException при вызове метода в Int32. - PullRequest
0 голосов
/ 10 октября 2019

Я новичок в IL в .NET и пытаюсь автоматически сгенерировать метод, который является чистым образцом.

Мое тестовое приложение генерирует указанный ниже IL, но оно генерирует исключение NullReferenceException в IL_002f, после получения значения свойства int в экземпляре, который, как известно, не равен NULL (как через 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; }
}

1 Ответ

1 голос
/ 10 октября 2019

Вы вызываете метод для необъектного объекта: целочисленное значение должно быть помещено в коробку, чтобы иметь возможность вызова метода. Я бы исправил ваш код следующим образом (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.

...