gpt4 book ai didi

c# - 了解非法的通用转换

转载 作者:太空宇宙 更新时间:2023-11-03 23:29:29 26 4
gpt4 key购买 nike

我无法理解为什么我正在执行的转换会抛出运行时异常,说明它是非法转换。我做了一些研究,发现 this answer ,这让我找到了 MSDN 文章 Covariance and Contravariance in Generics .但是,我仍然有点困惑,所以如果有人能帮助澄清,我将不胜感激。

这是 2 类类型的对象层次结构:

IMongoEntity (interface)
| - MongoEntity (abstract)
| | -SalesProject (concrete)
| | -ManagementProject (concrete)

IEntityService<T> where T : IMongoEntity (interface)
| -EntityService<T> where T : IMongoEntity (concrete superclass)
| | - MgmtService : EntityService<ManagementProject> (subclass)
| | - SalesService : EntityService<SalesProject> (subclass)

创建这两个非通用服务只是为了让我可以创建一些仅适用于那些特定类型的特定方法(本质上是对数据库的预定义查找)。

然后我有这一行,它抛出 InvalidCastException:

IEntityService<IMongoEntity> service = fromsales ? 
(IEntityService<IMongoEntity>)salesService :
(IEntityService<IMongoEntity>)mgmtService;

既然两个服务都派生自相同的接口(interface)和抽象类,并且使用的类型参数也派生自相同的抽象类,那么为什么这种转换是非法的?

注意:我有解决此问题的方法,所以我并不是真的在寻找解决方案,而是想了解为什么这是不允许的。

最佳答案

MyType<Base>MyType<Derived>没有任何继承关系,即使Derived源自 Base .这两种泛型只是两种不同的类型。

解决这个问题的一种方法是使用非通用接口(interface)作为基础接口(interface):

public interface IEntityService
{
void DoSomething(object item);
}

public interface IEntityService<T> : IEntityService
{
void DoSomething(T item);
}

此模式用于 .Net 类库(例如 IEnumerable/IEnumerable<T>IList/IList<T> )。

如果您知道您的接口(interface)仅将通用类型 ( T ) 用于输出,则可以使用 out关键字 IMyInterface<out T> .然后,您可以为 T 提供更派生的类型.这称为协方差。然后,这些方法的返回值将产生一个更符合消费者预期的派生类型,这是可以的。

如果它仅对输入使用通用类型,请使用 in关键字 IMyInterface<in T> .然后,您可以为 T 提供派生程度较低的类型.这称为逆变。然后,方法的输入参数将按预期获得更派生的类型,这没问题。

关于c# - 了解非法的通用转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32786420/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com