Общее ограничение на Т должно быть ссылочным типом и типом значений одновременно?

У меня проблема с пониманием того, как работают общие ограничения. Я думаю, что мне не хватает чего-то важного здесь. Я вложил свои вопросы в комментарии и был бы благодарен за предоставление некоторых объяснений.

//1st example:

class C <T, U>
    where T : class
    where U : struct, T
{
}
//Above code compiles well, 
//On first sight it looks like U might be reference type and value type
//at the same time. The only reason I can think of, is that T may be an 
//interface which struct can implement, Am I correct?

//2nd example

class CC<T, U>
    where T : class, new ()
    where U : struct, T
{
}

//I added also a reguirement for parameterless constructor
//and, much to my surprise, it still compiles what is
//a bit inexplicable for me.
//What 'U' would meet the requirement to be 
//value type, reference type and have a contructor at the same time?

Ответы

Ответ 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
{
}