полиморфное разрешение универсальных параметров в Unity registerType - PullRequest
3 голосов
/ 24 ноября 2010

Я пытаюсь сделать следующее и не удается:

class base {}

class derived1 : base {}

class derived2 : base {}

interface itr<t>
where t : class, base
{}

class c1: itr<derived1>
{}

class c2 : itr<derived2>
{}  

// Сбой следующих 2 регистраций:

_unityContainer.RegisterType<itr<base>, c1>("c1");

_unityContainer.RegisterType<itr<base>, c2>("c2");

Ошибка, которую я получаю, заключается в том, что второй параметр ввышеуказанные регистрации не могут быть вписаны в первый параметр, и эта регистрация недействительна.Любые предложения о том, как я могу это сделать?
Мне нужно сделать вышеупомянутое, а не регистрироваться с классами производным1 или производным2 в качестве общих параметров, потому что при разрешении я не хочу знать точный производный тип, который я разрешаю.Я хочу работать только с методами базового типа полиморфно.

1 Ответ

5 голосов
/ 24 ноября 2010

Вы не можете сделать это, потому что генерики не являются ковариантными.То есть тип itr<derived1> не может быть преобразован в itr<base>, хотя derived1 может быть преобразован в base.

. Вот пример того, почему с использованием класса List<T> каркаса:

List<string> list1 = new List<string>();
list1.Add("Hello, World!");

// This cast will fail, because the following line would then be legal:
List<object> list2 = (List<object>)list1; 

// ints are objects, but they are not strings!
list2.Add(1);

Таким образом, доступ к list1[1] вернет в штучной упаковке int в списке, который, как было объявлено, содержит string s.

Следовательно, это приведение не разрешено, так как оно прерветсясистема типов.

(В качестве примечания в разделе where t : class, base вам не нужно указывать class. base сам по себе является ссылочным типом, поэтому ограничение class является избыточным.)

...