Подтвердить что ты не робот

Избыточное общее ограничение?

Рассмотрим следующий общий метод:

public T2 Frob<T1, T2>(T1 item)
        where T1 : class, T2
        => item as T2;

Компилятор откажется от компиляции этого кода; Параметр типа "T2" не может использоваться с оператором "как", потому что у него нет ограничения типа класса или ограничения класса "

Хорошо, это легко разрешимо просто:

public T2 Frob<T1, T2>(T1 item)
        where T1 : class, T2
        where T2 : class
        => item as T2;

Но разве это не избыточно? Есть ли возможный T2, который не является class, учитывая ограничения, уже существующие для T1?

Мой вопрос не в том, почему этот "вывод" не был реализован в компиляторе, причина могла быть просто "никто не думал об этом", и все в порядке. Меня больше интересует знание правильности моего рассуждения в том, что T2 эффективно и во всех случаях ограничено class в первом примере, даже если оно явно не применяется.

4b9b3361

Ответ 1

Моя интерпретация этого, учитывая спецификации С# 5.0, говорят в 7.10.11, оператор as:

В операции формы E as T выражение E должно быть выражением, а T должно быть ссылочным типом, параметром типа, известным как ссылочный тип, или с нулевым значением тип.

Компилятор в этой точке рассматривает только T2 в этом блоке:

public T2 Frob<T1, T2>(T1 item)
        where T1 : class, T2
        => item as T2;

И он видит, что T2 сам не ограничен. Конечно, он мог бы вычесть, что в этом случае ожидается, что T1 будет ссылочным типом и наследует T2, поэтому сам T2 также должен быть ссылочным типом, но я уверен, что есть причины не делать этого.