首页 >后端开发 >C++ >为什么在 C# 中将 `MyEntityRepository` 转换为 `RepositoryBase` 失败?

为什么在 C# 中将 `MyEntityRepository` 转换为 `RepositoryBase` 失败?

DDD
DDD原创
2025-01-06 02:07:41227浏览

Why Does Casting `MyEntityRepository` to `RepositoryBase` Fail in C#?

泛型和转换:了解转换限制

尽管这种情况很常见,但将继承的类转换为基类可能很棘手,例如:尝试以下代码时遇到运行时异常:

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

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

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

此转换失败,因为RepositoryBase实际上并不是 MyEntityRepository 的基类。因此,从 MyEntityRepository 转换到 RepositoryBase 就可以了。无效。

这种限制的根本原因在于通用方差的概念。通用方差是指类型以协变或逆变方式更改其参数化的能力。但是,这种形式的泛型变体在 C# 中仅部分受支持,主要用于泛型接口和委托。

在更通用的上下文中,协变变体允许派生类型在给定场景中替换其基类型。这意味着从 RepositoryBase 派生的类型 MyEntityRepository 可以替换 RepositoryBase。在大多数情况下。然而,由于潜在的运行时冲突,这个假设并不普遍有效。

例如,考虑 RepositoryBase 中这样的方法:

void Add(T entity) { ... }

将 MyEntityRepository 转换为 RepositoryBase会打开向存储库添加非 MyEntity 实例的大门,这是不可取的。这表明不受限制的协变泛型方差可能会损害程序架构的完整性。

在 C# 4 中,泛型接口和委托中的引用类型允许泛型方差,但类不允许。有关更多详细信息,请参阅 Microsoft 的 MSDN 文档、Eric Lippert 的博客系列或 2010 年 7 月在 NDC 上进行的演示视频。

以上是为什么在 C# 中将 `MyEntityRepository` 转换为 `RepositoryBase` 失败?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn