NullReferenceException в Object.Equals(Объект, Объект)
ситуация
Я генерирую обертки с помощью 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 ответа
Не должен box
инструкция указать тип, который вы пытаетесь боксировать?
Например, вы не должны использовать...
box System.Int32 // or whatever
...скорее, чем...
box System.Object
Блок кода типа Tok (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
,