Ответ 1
В этом нет ничего плохого. Давайте рассмотрим определение ограничений для параметров типа:
-
T : class
- Аргумент типа T должен быть ссылочным типом, включая любой класс, интерфейс, делегат или тип массива. -
U : struct
- Аргумент типа U должен быть типом значения. -
U : T
- Аргумент типа U должен быть или выводиться из класса T.
Итак, все, что вам нужно сделать, это найти тип значения, полученный из ссылочного типа. Сначала это может показаться невозможным, но если вы подумаете немного сложнее, вы запомните, что все структуры получены из класса object
, поэтому это отлично подходит для обоих ваших примеров:
new C<object, int>();
Однако, если вы меняете struct
и class
, то он не будет компилироваться:
// Error - Type parameter 'T' has the 'struct' constraint so 'T'
// cannot be used as a constraint for 'U'
class C<T, U>
where T : struct
where U : class, T
{
}