Maison >développement back-end >C++ >Pourquoi la conversion de « MyEntityRepository » en « RepositoryBase » échoue-t-elle en C# ?

Pourquoi la conversion de « MyEntityRepository » en « RepositoryBase » échoue-t-elle en C# ?

DDD
DDDoriginal
2025-01-06 02:07:41273parcourir

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

Génériques et conversion : comprendre la limitation de conversion

Malgré son phénomène courant, la conversion de classes héritées en classes de base peut être délicate, comme en témoigne une exception d'exécution rencontrée lors de la tentative du code suivant :

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;

Ce casting échoue car RepositoryBase n'est pas réellement une classe de base de MyEntityRepository. En tant que tel, la conversion de MyEntityRepository vers RepositoryBase n'est pas valide.

La raison sous-jacente de cette limitation réside dans le concept de variance générique. La variance générique fait référence à la capacité d'un type à modifier ses paramétrages de manière covariante ou contravariante. Cependant, cette forme de variance générique n'est que partiellement prise en charge en C#, principalement pour les interfaces génériques et les délégués.

Dans un contexte plus générique, une variation covariante permet à un type dérivé de remplacer son type de base dans un scénario donné. . Cela signifie que MyEntityRepository, un type dérivé de RepositoryBase, pourrait remplacer RepositoryBase dans la plupart des cas. Cependant, cette hypothèse n'est pas universellement valable en raison de conflits d'exécution potentiels.

Par exemple, considérons une méthode comme celle-ci dans RepositoryBase :

void Add(T entity) { ... }

Casting MyEntityRepository vers RepositoryBase ouvrirait la porte à l’ajout d’instances non-MyEntity au référentiel, ce qui n’est pas souhaitable. Cela démontre qu'une variance générique covariante sans restriction peut compromettre l'intégrité de l'architecture d'un programme.

En C# 4, la variance générique est autorisée pour les types de référence au sein des interfaces génériques et des délégués, mais pas pour les classes. Pour des informations plus détaillées, reportez-vous à la documentation MSDN de Microsoft, à la série de blogs d'Eric Lippert ou à la vidéo d'une présentation donnée au NDC en juillet 2010.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn