我正在使用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)
....
public static bool Equals(object objA, object objB)
{
return objA == objB || (objA != null && objB != null && objA.Equals(objB));
}
正如你在反汇编中看到的那样,任何NullReferenceException
都不可能发生,因为它不会到达方法调用所在的部分。
正如我所说,使用ILGenerator生成孔代码,我认为这可能是错误的唯一可能来源。调用者只有里面的值类型,所以对象甚至不可能为null。
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)
答案 0 :(得分:3)
box
指令不应该指定您要尝试的类型吗?
例如,你不应该使用......
box System.Int32 // or whatever
......而不是......
box System.Object
答案 1 :(得分:2)
框 typeTok 操作码(ECMA-355 Partition 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
电话有效。我相信当前调用返回的是导致{{1}}的无效对象。