¿Por qué las estructuras genéricas y no genéricas se tratan de manera diferente cuando se construye una expresión que hace que el operador == sea anulable?

Esto parece un error al levantar a cero los operandos en estructuras genéricas.

Considere la siguiente estructura ficticia, que anulaoperator==:

struct MyStruct
{
    private readonly int _value;
    public MyStruct(int val) { this._value = val; }

    public override bool Equals(object obj) { return false; }
    public override int GetHashCode() { return base.GetHashCode(); }

    public static bool operator ==(MyStruct a, MyStruct b) { return false; }
    public static bool operator !=(MyStruct a, MyStruct b) { return false; }
}

Ahora considera las siguientes expresiones:

Expression<Func<MyStruct, MyStruct, bool>> exprA   = 
    (valueA, valueB) => valueA == valueB;

Expression<Func<MyStruct?, MyStruct?, bool>> exprB = 
    (nullableValueA, nullableValueB) => nullableValueA == nullableValueB;

Expression<Func<MyStruct?, MyStruct, bool>> exprC  = 
    (nullableValueA, valueB) => nullableValueA == valueB;

Los tres compilan y corren como se espera.

Cuando están compilados (usando.Compile()) producen el siguiente código (parafraseado al inglés de la IL):

La primera expresión que lleva soloMyStruct (no anulables) argumentos, simplemente llamadasop_Equality (nuestra implementación deoperator ==)

La segunda expresión, cuando se compila, produce un código que verifica cada argumento para ver siHasValue. Si ambos no lo hacen (ambos son iguales)null), devolucionestrue. Si solo uno tiene un valor, devuelvefalse. De lo contrario, llamadasop_Equality en los dos valores.

La tercera expresión comprueba el argumento anulable para ver si tiene un valor; si no, devuelve falso. De lo contrario, llamadasop_Equality.

Hasta ahora tan bueno.

Siguiente paso: hacer exactamente lo mismo con un tipo genérico - cambiarMyStruct aMyStruct<T> En todas partes en la definición del tipo, y cambiarlo aMyStruct<int> en las expresiones.

Ahora la tercera expresión compila pero lanza una excepción de tiempo de ejecuciónInvalidOperationException con el siguiente mensaje:

Los operandos para el operador 'Igual' no coinciden con los parámetros del método 'op_Equality'.

Yo esperaría que las estructuras genéricas se comporten exactamente igual que las no genéricas, con todo el levantamiento de nulos descrito anteriormente.

Así que mis preguntas son:

¿Por qué hay una diferencia entre estructuras genéricas y no genéricas?¿Cuál es el significado de esta excepción?¿Es este un error en C # / .NET?

El código completo para reproducir esto esdisponible en esta esencia.

Respuestas a la pregunta(2)

Su respuesta a la pregunta