NullReferenceException в Object.Equals (Объект, Объект) - PullRequest
3 голосов
/ 28 февраля 2012

Положение

Я создаю оболочки, используя ILGenerator. Я использую Object.Equals(Object, Object) Для реализации сравнения равенства полей оболочки. Отладчик выдает NullReferenceException со следующей трассировкой стека.

at System.Object.Equals(Object objA, Object objB)
at HIDDEN.StateTransitionWrapper.op_Equality(StateTransitionWrapper , StateTransitionWrapper )
at HIDDEN.StateTransitionWrapper.Equals(Object )
at System.Object.Equals(Object objA, Object objB)
at HIDDEN.StationEventCompositeWrapper.op_Equality(StationEventCompositeWrapper , StationEventCompositeWrapper )
at HIDDEN.StationEventCompositeWrapper.Equals(Object )
at System.Object.Equals(Object objA, Object objB)
at HIDDEN.CompareResult..ctor(Object object0, Object object1, String fieldName) 
....

Object.Equals (Объект, Объект) - Разборка

public static bool Equals(object objA, object objB)
{
    return objA == objB || (objA != null && objB != null && objA.Equals(objB));
}

Как вы можете видеть в разборке, невозможно, чтобы любой NullReferenceException мог произойти, потому что он не достигнет той части, где находится вызов метода.

Возможные проблемы

Как я уже сказал, код дыры генерируется с помощью ILGenerator, и я думаю, что это может быть единственным возможным источником ошибки. Вызывающий объект имеет только типы значений внутри, поэтому даже невозможно, чтобы объект был нулевым.

Вызов IL-кода

IL_0040: ldarg.0
IL_0041: call instance valuetype [HIDDEN]HIDDEN.StationStateType HIDDEN.StateTransitionWrapper::get_StationState()
IL_0046: box [mscorlib]System.Object
IL_004b: ldarg.1
IL_004c: call instance valuetype [HIDDEN]HIDDEN.StationStateType HIDDEN.StateTransitionWrapper::get_StationState()
IL_0051: box [mscorlib]System.Object
IL_0056: call bool [mscorlib]System.Object::Equals(object, object)

Ответы [ 2 ]

3 голосов
/ 28 февраля 2012

Разве инструкция box не должна указывать тип, который вы пытаетесь пометить?

Например, не следует ли вам использовать ...

box System.Int32  // or whatever

...отличнее ...

box System.Object
2 голосов
/ 29 февраля 2012

Блок typeTok код операции (ECMA-355 Раздел III, раздел 4.2) берет val из стека и преобразует его в obj .Если typeTok является ссылочным типом, инструкция box возвращает val без изменений [выделение добавлено] как obj .Когда typeTok является типом значения (по крайней мере, необнуляемого), с другой стороны, box создает новый объект и копирует данные из val в новый объект,

Как указывает @LukeH, указанный выше IL использует команду box [mscorlib]System.Object, когда она должна использовать box [HIDDEN]HIDDEN.StationStateType.Последний по-прежнему будет возвращать object, который будет действителен для вызова Object.Equals(Object, Object).Я считаю, что текущий вызов возвращает недопустимый объект, который вызывает NullReferenceException.

...