polymorphic resolution of generic parameters in Unity registerType

僤鯓⒐⒋嵵緔 提交于 2019-12-20 02:27:41

问题


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.


回答1:


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 strings.

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.)



来源:https://stackoverflow.com/questions/4269279/polymorphic-resolution-of-generic-parameters-in-unity-registertype

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!