Почему общие и неуниверсальные структуры обрабатываются по-разному при построении выражения, которое поднимает оператор == до нуля?

Это похоже на ошибку при поднятии до нуля операндов на общих структурах.

Рассмотрим следующую фиктивную структуру, которая переопределяет:operator==

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; }
}

Теперь рассмотрим следующие выражения:

Expression exprA   = 
    (valueA, valueB) => valueA == valueB;

Expression exprB = 
    (nullableValueA, nullableValueB) => nullableValueA == nullableValueB;

Expression exprC  = 
    (nullableValueA, valueB) => nullableValueA == valueB;

Все три компилируются и запускаются, как и ожидалось.

Когда они'перекомпилируется (используя.Compile()) они производят следующий код (перефразированный на английский из IL):

Первое выражение, которое принимает толькоMyStruct (не обнуляемый) args, просто вызовop_Equality (наша реализация)operator ==

Второе выражение, когда скомпилировано, производит код, который проверяет каждый аргумент, чтобы увидеть, если онHasValue, Если оба нет (оба равныnull), возвращаетtrue, Если только один имеет значение, возвращаетfalse, В противном случае звонкиop_Equality на двух значениях.

Третье выражение проверяет обнуляемый аргумент, чтобы увидеть, имеет ли оно значение - если нет, возвращает false. В противном случае звонки.op_Equality

Все идет нормально.

Следующий шаг: сделать то же самое с универсальным типом - изменитьMyStruct вMyStruct везде в определении типа, и измените его наMyStruct в выражениях.

Теперь третье выражение компилируется, но выдает исключение времени выполненияInvalidOperationException со следующим сообщением:

Операнды для оператораРавный» не соответствуют параметрам методаop_Equality.

Я ожидал бы, что родовые структуры будут вести себя точно так же, как и неуниверсальные, со всеми отменяемыми значениями, описанными выше.

Итак, мои вопросы:

Почему существует разница между общими и неуниверсальными структурами?В чем смысл этого исключения?Это ошибка в C # /. NET?

Полный код для воспроизведения этогодоступно на этой сути.

Ответы на вопрос(2)

Ваш ответ на вопрос