Unity registerType中泛型参数的多态分辨率

时间:2010-11-24 16:46:59

标签: c# generics inversion-of-control unity-container

我正在尝试执行以下操作并失败:

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");

我得到的错误是上述注册中的第二个参数不能被类型转换为第一个参数,并且该注册无效。关于如何做到这一点的任何建议?
我需要执行上述操作,而不是使用derived1或derived2类作为通用参数进行注册,因为在解析时我不想知道我正在解析的确切派生类型。我只想多态地使用基类型方法。

1 个答案:

答案 0 :(得分:5)

你不能这样做,因为泛型不是协变的。也就是说,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

因此,不允许进行此强制转换,因为它会破坏类型系统。

(作为旁注,在条款where t : class, base中,您不需要指定classbase本身是引用类型,因此class约束是多余的。)