简体   繁体   English

Object.Equals(Object,Object)中的NullReferenceException

[英]NullReferenceException at Object.Equals(Object, Object)

Situation 情况

I'm generating wrappers by using the ILGenerator. 我正在使用ILGenerator生成包装器。 I use Object.Equals(Object, Object) For the implementation of the equality compare of the wrapper fields. 我使用Object.Equals(Object, Object)来实现包装器字段的相等比较。 The debugger throws a NullReferenceException with the following stack trace. 调试器抛出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(Object, Object) - Disassembly Object.Equals(Object,Object) - 反汇编

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

As you can see in the disassembly it's impossible that any NullReferenceException can occur because it won't reach the part where the method call is. 正如你在反汇编中看到的那样,任何NullReferenceException都不可能发生,因为它不会到达方法调用所在的部分。

Possible problems 可能的问题

As i said the hole code is generated by using the ILGenerator and i think this could the only possible source for the error. 正如我所说,通过使用ILGenerator生成孔代码,我认为这可能是错误的唯一可能来源。 The caller has only value types inside, so it's not even possible that the object is null. 调用者内部只有值类型,因此该对象甚至不可能为null。

Calling IL-Code 致电IL-Code

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)

Shouldn't the box instruction specify the type that you're trying to box? box指令不应该指定你想要盒子的类型吗?

For example, shouldn't you be using... 例如,你不应该使用......

box System.Int32  // or whatever

...rather than... ...而不是...

box System.Object

The box typeTok opcode (ECMA-355 Partition III, section 4.2) takes val from the stack and converts it to obj . box typeTok操作码(ECMA-355 Partition III,第4.2节)从堆栈中获取val并将其转换为obj If typeTok is a reference type, the box instruction returns val unchanged [emphasis added] as obj . 如果typeTok是引用类型,则box指令返回val 不变 [emphasis added]作为obj When typeTok is a value type (at least a non-nullable one), on the other hand, box creates a new object and copies the data from val into the new object. typeTok是一个值类型(至少是一个非可空的值)时,另一方面, box创建一个新对象并将数据从val复制到新对象中。

As @LukeH points out, the IL above is using the command box [mscorlib]System.Object when it should use box [HIDDEN]HIDDEN.StationStateType . 正如@LukeH指出的那样,上面的IL正在使用命令box [mscorlib]System.Object ,它应该使用box [HIDDEN]HIDDEN.StationStateType The latter will still return an object which will be valid for the Object.Equals(Object, Object) call. 后者仍然会返回一个object ,这将是有效的Object.Equals(Object, Object)呼叫。 I believe the current call is returning an invalid object that is causing the NullReferenceException . 我相信当前调用返回一个导致NullReferenceException的无效对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM