Unity registerType中通用参数的多态分辨率 [英] polymorphic resolution of generic parameters in Unity registerType
问题描述
class base {}
class derived1:base {}
class derived2:base {}
interface itr< t>
其中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类作为泛型参数,因为在解决时我不想知道确切的派生类型我正在解决。我只想用多态的基本类型方法工作。
你不能这样做,因为泛型不是协变的。也就是说, itr< derived1>
类型不能转换为 itr< base>
,即使 derived1
可以转换为 base
。
下面是一个例子,使用框架 List< T>
class:
List< string> list1 = new List< string>();
list1.Add(Hello,World!);
//这个强制转换将失败,因为下面这行代码是合法的:
List< object> list2 =(List< object>)list1;
// ints是对象,但它们不是字符串!
list2.Add(1);
因此,访问 list1 [1]
会返回一个名为 int
的列表被声明为包含 string
s。
因此,这种转换是不允许的,因为它会破坏类型系统。
(注意,在其中t:class,base
,您不需要指定 class
。 base
本身是一个引用类型,所以 class
约束是多余的。)
I am trying to do the following and failing:
class base {}
class derived1 : base {}
class derived2 : base {}
interface itr<t>
where t : class, base
{}
class c1: itr<derived1>
{}
class c2 : itr<derived2>
{}
//The following 2 registrations fail:
_unityContainer.RegisterType<itr<base>, c1>("c1");
_unityContainer.RegisterType<itr<base>, c2>("c2");
The error I get is that the second parameter in the above registrations cannot be typecast into the first parameter and this registration is not valid. Any suggestions on how I can do this?
I need to do the above instead of registering with the derived1 or derived2 classes as generic parameters because while resolving I don't want to have to know the exact derived type I am resolving. I only want to work with base type methods polymorphically.
You cannot do this because generics are not covariant. That is, the type itr<derived1>
cannot be converted to itr<base>
, even though derived1
can be converted to base
.
Here's an example of why, using the framework List<T>
class:
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);
So accessing list1[1]
would return a boxed int
in a list that was declared to contain string
s.
Therefore, this cast is not allowed since it would break the type system.
(As a side note, in the clause where t : class, base
, you do not need to specify class
. base
itself is a reference type, so the class
constraint is redundant.)
这篇关于Unity registerType中通用参数的多态分辨率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!