ホームページ > バックエンド開発 > C++ > C# で `MyEntityRepository` から `RepositoryBase` へのキャストが失敗するのはなぜですか?

C# で `MyEntityRepository` から `RepositoryBase` へのキャストが失敗するのはなぜですか?

DDD
リリース: 2025-01-06 02:07:41
オリジナル
260 人が閲覧しました

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) { ... }
ログイン後にコピー

Casting MyEntityRepository to RepositoryBaseこれは、MyEntity 以外のインスタンスをリポジトリに追加する可能性がありますが、これは望ましくありません。これは、無制限の共変ジェネリック分散がプログラムのアーキテクチャの整合性を損なう可能性があることを示しています。

C# 4 では、ジェネリック バリアンスは、ジェネリック インターフェイスおよびデリゲート内の参照型に対して許可されていますが、クラスに対しては許可されていません。詳細については、Microsoft の MSDN ドキュメント、Eric Lippert のブログ シリーズ、または 2010 年 7 月に NDC で行われたプレゼンテーションのビデオを参照してください。

以上がC# で `MyEntityRepository` から `RepositoryBase` へのキャストが失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート