将类从asType转换为类 :无法施放
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将类从asType转换为类 :无法施放相关的知识,希望对你有一定的参考价值。
我试图将asType()的对象转换为它的父类。
这是我的结构(我认为不需要细节,只是类描述和继承)
public class Entity1: Entity
{}
public class Entity2: Entity
{}
public class Entity
{}
public class ClassM1 : MigrationBaseReverse<Entity1, Entity2>
{}
public class MigrationBaseReverse<T, M> : MigrationBase<T, M>
where T : Entity, new()
where M : Entity, new()
{}
public class MigrationBase<T, M>
where M : Entity, new()
where T : Entity, new()
{}
我所做的 :
我像这样存储了ClassM1的类型信息(ti是一个TypeInfo):
Type type = ti.AsType();
然后,我用Activator创建一个新实例
instance = Activator.CreateInstance(type);
然后我(或者直接在Activator中,但得到相同的结果),尝试将它像它的父母一样投射
instance as MigrationBase<Entity, Entity>
但这不起作用,我得到了null,而这显然有效
instance as MigrationBase<Entity1, Entity2>
由于Entity1和Entity2继承自实体,我认为我可以使用Entity,但似乎不是。
我也试过像这样的演员:
(MigrationBase<Entity1, Entity2>) instance
但我在演员阵容中遇到如下错误:
Unable to cast object of type 'ClassM1' to type 'MigrationBase`2[Entity,Entity]'.
我应该补充一点,我尝试使用MigrationBaseReverse进行所有这些转换
任何想法,将不胜感激。
我不确定标题,因为解释起来很复杂,所以如果一个人知道一个更好的标题,那就不要害怕编辑。
我希望你能得到你需要的所有信息。
这个问题每周在SO上被问到1000次。
首先,c#中的泛型类型差异仅允许在接口和委托上使用。你没有。
其次,为了允许类型差异,您必须证明它是安全的。 IList<string>
不是IList<object>
,因为转换只是不安全; IList<T>
在T
中是不变的。
IEnumerable<string>
是IEnumerable<object>
,因为IEnumerable<out T>
在T
中是协变的。
使用您提供的代码,无法确定理论上的IMigrationBase<T, M>
是否可以在T
和M
中协变。如果可以,那么您的转换将起作用,如果不能,则不会。
关于这个主题的一个非常有用的读物:Covariance and Contravariance in C# series。一定要阅读第六部分。
更新:
好吧,想象你的理论IMigrationBase<T, M>
看起来像这样:
interface IMigrationBase<T, M>
where T: Entity
where M: Entity
{
M Migrate(T entity) { .... }
}
想象一下这是合法的:
var m1 = new ClassM1();
IMigrationBase<Entity, Entity> m = m1; //illegal but lets play along
然后我们可能有以下可怕的想法:
m.Migrate(new Entity3()); //Legal but ouch!
而现在m
,真的是m1
,突然试图迁移一个它一无所知的Entity3
类型。发生这种情况是因为T
中的界面不协变(M
中的协变性,而T
中的反变量),转换永远不会安全。如果你想要类型方差,这个理论界面的真正声明将是IMigrationBase<in T, out M>
,以下转换将是安全的:
IMigrationBase<Entity1, Entity> m = m1;
如果您的界面在T
和M
中是协变的,那么您尝试的转换将是安全的。你怎么知道它在T
和M
的协变性?好吧,拇指的规则(不是100%准确,但大部分时间都足够好),T
和M
应该只是接口成员的输出(out
),从不输入(in
)。如果您的接口需要使用其通用类型之一作为输入,那么它在泛型类型参数中永远不会是协变的。
以上是关于将类从asType转换为类 :无法施放的主要内容,如果未能解决你的问题,请参考以下文章