Heim >Backend-Entwicklung >C++ >Warum schlägt die Umwandlung von einem abgeleiteten in einen generischen Basistyp in C# fehl?

Warum schlägt die Umwandlung von einem abgeleiteten in einen generischen Basistyp in C# fehl?

Patricia Arquette
Patricia ArquetteOriginal
2025-01-06 02:19:40510Durchsuche

Why Does Casting from a Derived to a Base Generic Type Fail in C#?

Umwandlung von abgeleiteten in generische Basistypen: Eintauchen in die Inkompatibilität

In C# führt das Vererbungsmodell für generische Typen häufig zu Fragen zu Umwandlung von abgeleiteten in Basistypen. Diese Abfrage untersucht die zugrunde liegende Komplexität und warum eine direkte Umwandlung von einer abgeleiteten Klasse in ihre Basisklasse möglicherweise fehlschlägt.

Das Rätsel der Umwandlung

Bedenken Sie den folgenden Codeausschnitt:

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

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

Lassen Sie uns nun die Problematik untersuchen Zeile:

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

Führen Sie diesen Code aus und es wird eine Laufzeitausnahme auftreten. Warum schlägt dieser Umwandlungsversuch fehl?

Generische Varianz: Die Illusion der Kompatibilität

Intuitiv könnten wir annehmen, dass eine abgeleitete Klasse wie MyEntityRepository auch ein Typ ihrer Basis ist Klasse, RepositoryBase. Im Bereich der Generika ist diese Annahme jedoch nicht immer gültig.

Generische Varianz bezieht sich auf die Fähigkeit eines generischen Typs, seinen Typparameter durch einen mehr oder weniger abgeleiteten Typ zu ersetzen. Leider unterstützt C# in bestimmten spezifischen Szenarien nur begrenzte Varianz.

In diesem Beispiel ist RepositoryBase ist nicht eine Basisklasse von MyEntityRepository. Dies liegt daran, dass der Typparameter T in Bezug auf seinen Basistyp weder kovariant noch kontravariant ist.

Kovarianz: Eine einseitige Reise

Kovarianz ermöglicht den Verweis auf eine generische Klasse ein stärker abgeleiteter Typparameter als seine Basisklasse. Dies ist in bestimmten Situationen zulässig, in denen der generische Typ seinen Typparameter nur zum Zurückgeben von Werten verwendet. Dies ist hier jedoch nicht der Fall.

Kontravarianz: Ein harter Kampf

Kontravarianz hingegen ermöglicht es einem generischen Typ, einen weniger abgeleiteten Typparameter zu verwenden als seine Basisklasse beim Akzeptieren von Werten. Aber auch dies ist in diesem Zusammenhang nicht anwendbar.

Der Schutz der generischen Sicherheit

Ohne generische Varianz könnte die Umwandlung von einem abgeleiteten in einen Basistyp zu unerwarteten Ergebnissen führen Verhalten und mögliche Laufzeitfehler. Wenn beispielsweise RepositoryBase Die Klasse hatte eine Methode, die nur mit Entitäten vom Typ EntityBase arbeiten konnte und MyEntityRepository in RepositoryBase umwandelte. könnte ungültige Vorgänge zulassen.

Umwandlungsfalle vermeiden

Wenn Sie zwischen generischen Typen umwandeln müssen, ist es wichtig, die Einschränkungen der generischen Varianz zu verstehen. Erwägen Sie die Einführung einer expliziten Umwandlung von der Basisklasse in die abgeleitete Klasse oder die Verwendung alternativer Entwurfsmuster wie der Factory-Methode oder des Bridge-Musters, um diese Fallstricke zu vermeiden.

Das obige ist der detaillierte Inhalt vonWarum schlägt die Umwandlung von einem abgeleiteten in einen generischen Basistyp in C# fehl?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn