Kann eine Basisklassenmethode den Typ der abgeleiteten Klasse zurückgeben?

8

Basierend auf den anderen Posts, die ich gelesen habe, scheint es, dass dies nicht möglich ist, aber ich dachte, ich würde posten, was ich zu tun versuche und sehen, ob jemand eine Lösung kennt.

Ich versuche, eine "Clone ()" -Methode zu Klassen hinzuzufügen, die aus einem Telerik Open Access-Domänenmodell generiert wurden. Kein Problem. Ich konnte herausfinden, wie man den generierten Entitätsmodellen eine Basisklasse hinzufügt, um diese Klassen anhand ihrer Basisklasse zu identifizieren. ( Alle Entitäten erben von einer Basisklasse )

Ich möchte, dass ALLE Entity-Model-Klassen in der Lage sind, selbst zu klonen. Ich habe auch dafür eine Lösung gefunden. ( Klonen von Objekten )

Jetzt habe ich eine Basisklasse und möchte jeder Klasse, die von dieser Basisklasse abgeleitet ist, eine Clone () - Funktion hinzufügen. Also ... es scheint, dass die Basisklasse der natürliche Ort ist, um es zu sagen ... richtig?

%Vor%

Ich füge die geschützte generische Clone () -Methode hinzu, da wir auf der Basisklassenebene den Typ, den wir klonen, nicht kennen. Die Clone () - Methode muss vom Entitätsmodell selbst implementiert werden, um den spezifischen Typ bereitzustellen, der geklont wird.

%Vor%

Das funktioniert gut, aber garantiert nicht, dass abgeleitete Klassen eine Clone () -Methode öffentlich verfügbar machen. Daher habe ich ein abstract Clone () hinzugefügt em> -Methode an die Basis, die erfordert die abgeleitete Klasse, um eine öffentliche Clone () -Methode zu implementieren.

%Vor%

Ich gebe es einen Rückgabetyp der Basisklasse selbst; Jede Implementierung MUSS einen Wert zurückgeben, der der DBEntityBase entspricht, was natürlich alle abgeleiteten Klassen tun. Da die Clone () - Methode einen Typ der abgeleiteten Klasse selbst zurückgibt, dann ... scheint es sinnvoll zu sein, dass dies funktionieren würde.

%Vor%

Beim Aufbau bekomme ich jedoch den Fehler ..

  

'DeliverableEntity' implementiert das geerbte abstrakte Element nicht   'DBEntityBase.Clone ()'

Vermutlich aufgrund des Rückgabetyps.

Ich weiß, dass ich die Clone () -Methode einfach in eine separate Utility-Klasse schreiben und nicht direkt in jedes Entity-Modell implementieren könnte ... das würde mich um mein Problem bringen (und wahrscheinlich viel Implementierungscode speichern), aber ich frage mich immer noch, warum das nicht funktioniert. Es scheint, als sollte es einen Weg geben, dies zu tun.

AKTUALISIEREN

Als Antwort auf @ Luanns erste Antwort (danke) habe ich die Änderung auf "override" geändert ...

%Vor%

und erhalte jetzt den folgenden Fehler ...

  

Rückgabetyp muss "DBEntityBase" sein, um dem überschriebenen Element zu entsprechen   'DBEntityBase.Clone ()'

LÖSUNG

Dank Flynn1179 konnte ich mich wieder vorwärts bewegen. Ich dachte, ich würde mir einen Moment Zeit nehmen, um zu dokumentieren, was ich hier gemacht habe, um sie später zu recherchieren.

Anstatt für jedes Entitätsmodell im ORM eine partielle Klasse zu erstellen und eine abstrakte Methode zu implementieren, habe ich wie vorgeschlagen eine einzelne Erweiterungsmethode erstellt.

%Vor%

Einige Dinge zu beachten ...

  • Platzieren Sie diese Klasse im selben Namespace wie die Entitätsmodelle. Wenn es sich in einem anderen Namespace befindet, müssen Sie diesen Namespace hinzufügen, um Zugriff auf die Methode zu erhalten.
  • Ich habe die Einschränkung für den generischen Typ nur für alle Klassen definiert, die die Klasse DBEntityBase erben. Da ich alle meine Entity-Model-Klassen von dieser Basisklasse abgeleitet habe, weiß ich, dass alle diese Methode verfügbar machen werden, aber auch, dass jede Klasse, die NICHT von dieser Klasse abgeleitet ist, diese Fähigkeit nicht besitzt.
  • Die Erweiterungsmethode und die Klasse, die sie enthält, müssen static sein

Jetzt ist der coole Teil, dass ALLE Entitäten Zugriff auf die Funktion haben ...

%Vor%

Ich liebe diese Lösung, da sie die Einfachheit einer Basisklasse hat, in der die Implementierung an einem einzigen Ort definiert ist (während ich versuchte, eine abstrakte Methode in jeder abgeleiteten Klasse einzeln zu implementieren) und da sie der DBEntityBase-Klasse zugeordnet ist Im selben Namespace wird es Teil des durch die Basisklasse definierten "Vertrags", was bedeutet, dass ich darauf zählen kann, dass es immer verfügbar ist, wenn ich eine von DBEntityBase abgeleitete Klasse habe.

    
Gary O. Stenstrom 20.08.2015, 15:42
quelle

1 Antwort

7

Auf vielfachen Wunsch ..

Versuchen Sie eine Erweiterungsmethode:

%Vor%

Ich muss ehrlich sein, ich dachte nicht, dass das funktionieren würde, da ich erwartet hatte, dass C # nicht genau bestimmen könnte, wofür es eine Erweiterung von ist. Anscheinend tut es das aber!

    
Flynn1179 20.08.2015, 16:17
quelle

Tags und Links