Question

Situation

I'm generating wrappers by using the ILGenerator. I use Object.Equals(Object, Object) For the implementation of the equality compare of the wrapper fields. The debugger throws a NullReferenceException with the following stack trace.

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

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.

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. The caller has only value types inside, so it's not even possible that the object is null.

Calling 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)
Was it helpful?

Solution

Shouldn't the box instruction specify the type that you're trying to box?

For example, shouldn't you be using...

box System.Int32  // or whatever

...rather than...

box System.Object

OTHER TIPS

The box typeTok opcode (ECMA-355 Partition III, section 4.2) takes val from the stack and converts it to obj. If typeTok is a reference type, the box instruction returns val unchanged [emphasis added] as 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.

As @LukeH points out, the IL above is using the command box [mscorlib]System.Object when it should use box [HIDDEN]HIDDEN.StationStateType. The latter will still return an object which will be valid for the Object.Equals(Object, Object) call. I believe the current call is returning an invalid object that is causing the NullReferenceException.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top