Общее ограничение на T, чтобы быть ссылочным типом и типом значения одновременно? - PullRequest
14 голосов
/ 09 января 2011

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

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

13 голосов
/ 09 января 2011

В этом нет ничего плохого.Давайте посмотрим на определение ограничений на параметры типа :

  • 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
{
}
...