泛型和铸造 - 不能施放继承类的基类 [英] Generics and casting - cannot cast inherited class to base class

查看:115
本文介绍了泛型和铸造 - 不能施放继承类的基类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这是老了,但我仍然没有很好的理解这些问题。谁能告诉我,为什么下面不工作(约抛出一个铸造运行除外)?

I know this is old, yet I am still not very good with understanding those problems. Can anyone tell me why the following does not work (throws a runtime exception about casting)?

public abstract class EntityBase { }
public class MyEntity : EntityBase { }

public abstract class RepositoryBase<T> where T : EntityBase { }
public class MyEntityRepository : RepositoryBase<MyEntity> { }

而现在的铸造生产线:

And now the casting line:

MyEntityRepository myEntityRepo = GetMyEntityRepo(); // whatever
RepositoryBase<EntityBase> baseRepo = (RepositoryBase<EntityBase>)myEntityRepo;

所以,任何人都可以解释这是怎么无效?而且,我你没有心情解释 - 有code的一条线,我可以用它来真正做到这一点投

So, can anyone explain how is this invalid? And, I you are not in the mood to explain - is there a line of code I can use to actually do this cast?

推荐答案

RepositoryBase&LT; EntityBase&GT; 是的的基类的 MyEntityRepository 。您正在寻找的通用方差的存在于C#程度有限,但不会在这里适用。

RepositoryBase<EntityBase> is not a base class of MyEntityRepository. You're looking for generic variance which exists in C# to a limited extent, but wouldn't apply here.

假设你的 RepositoryBase&LT; T&GT; 类有这样的方法:

Suppose your RepositoryBase<T> class had a method like this:

void Add(T entity) { ... }

现在考虑:

MyEntityRepository myEntityRepo = GetMyEntityRepo(); // whatever
RepositoryBase<EntityBase> baseRepo = (RepositoryBase<EntityBase>)myEntityRepo; 
baseRepo.Add(new OtherEntity(...));

现在您已经添加了一个别样的实体到 MyEntityRepository ...这不可能是正确的。

Now you've added a different kind of entity to a MyEntityRepository... and that can't be right.

基本上,普通的方差是只在某些情况下是安全的。尤其是通用的的(这是你描述这里)是唯一安全的,当你只会得到API值走出去;通用的逆变的(工作反过来)是唯一安全的,当你只是没有把值为的API(例如,可以通过区域比较任意两个形状一般比较可以被看作是一个比较的平方)。

Basically, generic variance is only safe in certain situations. In particular generic covariance (which is what you're describing here) is only safe when you only ever get values "out" of the API; generic contravariance (which works the other way round) is only safe when you only ever put values "into" the API (e.g. a general comparison which can compare any two shapes by area can be considered as a comparison of squares).

在C#4,这是可以通用的接口和通用的代表,而不是类 - 只与引用类型。请参见进一步的信息MSDN ,阅读&LT;即插即用GT;读的C#的深入,第二版,第13章&LT; /插头&GT;或埃里克利珀的博客系列的主题演讲。另外,我在2010年7月给了一个小时的说说这在NDC - 视频是在这里使用 ;只要搜索变异。

In C# 4 this is available for generic interfaces and generic delegates, not classes - and only with reference types. See MSDN for further information, read <plug>read C# in Depth, 2nd edition, chapter 13</plug> or Eric Lippert's blog series on the topic. Also, I gave a one hour talk about this at NDC in July 2010 - the video is available here; just search for "variance".

这篇关于泛型和铸造 - 不能施放继承类的基类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆