Erstellen eines geklonten Kopie Unterklasse von baseclass
Betrachten Sie dieses Szenario:
public class Base
{
public int i;
}
public class Sub : Base
{
public void foo() { /* do stuff */}
}
Und dann möchte ich, gegeben eine Instanz von Base
bekommen eine geklonte Instanz der Sub
(mit i=17 in diesem Fall) so, dass ich anrufen kann foo
in der Unterklasse.
Base b = new Base { i=17 };
Sub s = CloneAndUpcast(b);
s.foo();
Jedoch, wie kann ich CloneAndUpcast
?
Ich denke, das sollte möglich sein, die rekursiv Klonen alle Base
-Mitglieder und-Eigenschaften mit der spiegelung. Aber einiges an Arbeit.
Jemand mit besser, ordentlicher Ideen?
PS. Das Szenario, wo ich denke über die Verwendung von dies ist ein Satz von "einfachen" Klassen, die in einer baumartigen Struktur (keine zyklische Graphen oder ähnliches hier) und alle Klassen sind einfache value-Inhaber. Der plan ist, eine blöde Schicht, die alle Werte und dann eine ähnliche Menge von Klassen (die Unterklassen), die tatsächlich enthält die business-Logik der Wert-Inhaber sollte nicht bewusst sein. In der Regel schlechte Praxis, ja. Ich denke, es funktioniert in diesem Fall.
- Sie kann nicht genau das tun, was Ihr bittet. Es gibt eine Menge Gründe, warum, aber es genügt zu sagen, selbst wenn man das könnte, es ist generell eine schlechte Praxis. Wenn Sie können, geben Sie uns das breitere problem, das Sie lösen möchten, können wir Ihnen helfen das richtige Muster.
- Das klingt wie eine Frage weist auf ein Allgemeines problem ist gelöst der falsche Weg. Weder der Schuh noch die Flasche aus Glas angebracht ist. Siehe: weblogs.asp.net/alex_papadimoulis/archive/2005/05/25/...
- Ich denke, die Dinge, die Sie versuchen, zu erreichen, könnte darauf hindeuten, ein design-Problem. Auch, da
i
ist privat zubase
Klasse, diesub
kann es nicht verwenden, sowieso, also je nach ArbeitsweiseBase
es gibt keine Notwendigkeit zu kopieren, das Feld. i
war gedacht als Beispiel für die public-member. Sorry da.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist eine Möglichkeit (von vielen Möglichkeiten), dass Sie etwas tun können, wie Sie gefragt haben. Ich bin mir nicht sicher, das ist sehr hübsch und kann sein Art hässlich zu Debuggen, aber ich denke, es funktioniert:
Im Grunde, wie Sie vorgeschlagen, Sie verwenden Sie reflektion, um zu Durchlaufen und die Eigenschaften des Objekts (ich
i
undj
als öffentliche Eigenschaften) und setzen Sie die Werte entsprechend in das geklonte Objekt. Der Schlüssel ist die Verwendung von Generika zu sagen, CloneAndUpcast welche Art Sie es zu tun haben. Sobald Sie das tun, ist es ziemlich einfach.Hoffe, das hilft. Viel Glück!
Könnten Sie AutoMapper zu vermeiden, um die Langeweile zu schreiben, die copy-Konstruktoren.
und Sie müssen zu laufen, dieses mal, wenn Ihre Anwendung startet
Können Sie herunterladen AutoMapper von https://github.com/AutoMapper/AutoMapper
Pro die "Gang of Four" : "Favor composition over inheritance" und dies ist ein perfekter Grund, so zu tun...
Wenn wir eine Oberklasse, die wie folgt aussieht:
Der Oberklasse können ganz einfach dekorieren die Klasse "Person" hinzufügen von Eigenschaften, die nicht in Person-Klasse.
Aber was passiert, wenn der Superklasse Dekorationen sind nur für die GUI? Zum Beispiel ein boolescher Wert, der angibt, "Ausgewählt". Wir sind noch in der Lage zu erhalten, alle Personen aus der DB in eine Liste, sondern wir führen Sie in Schwierigkeiten, die versuchen, um die Oberklasse, und führen Sie die DB-Ergebnisse.
Der compiler meckert, weil die Oberklasse ist nicht eine Person, die für den compiler ist es ein Superklasse. Der einzige Weg, um füllen Sie die Eigenschaften der Person, die Unterklasse wird zu iterieren und jeweils einer an... so wie hier.
Ziemlich langweilig in der Tat. Aber es gibt einen besseren Weg.... Machen Sie nicht Superklasse Erben von Person
Dies gibt uns die "Containment" - Die Oberklasse enthält jetzt eine Klasse "Person".
Jetzt können wir dies tun:
Den Verbraucher von dieser Klasse muss jetzt qualifizieren die Eigenschaften der Oberklasse/Person...
Die Schönheit dieser ist, dass in der Zukunft, können Sie jede beliebige andere container, die Sie wollen, und es wird KEINE Auswirkungen auf andere Container. Sie können auch morph der Superklasse-alles, was es enthält. Wenn jedes der enthaltenen Klassen werden zu Schnittstellen, dann ist das ein Schritt weiter die Straße hinunter.
Gut, da
b
ist nicht einSub
können wir nicht "Klonen", als ein.Wenn
Base
hat eine geeignete Kombination von Konstruktor und öffentlichen Eigenschaften zu lassen, einen Konstruktor inSub
sicherzustellen, dass seine Basis hätte daher den gleichen Zustand wieb
, die wir dann verwenden konnten.Ich denke, ich würde by-pass an der ganzen Sache, obwohl. Wenn alle wir Sorge über, ist, dass
s
haben die gleichen Staat in seiner Basis alsb
, und es hat nicht anderen Staat, dass wir gehen zu interessieren (sonst hätten wir führen Sie durch dieCloneAndUpcast
Methode), dann brauchen wirs
überhaupt?Einer statischen Methode könnte eine
Base
und wir konnte einfachstatic public void foo(Base bc)
. Man könnte auch definieren es als eine Erweiterung Methodestatic public void foo(this Base bc)
und dann der code den Aufruf alsb.foo()
. Das einzige, was diese uns nicht lassen tun, dassCloneAndUpcast()
lässt uns tun, ist für den Zugriff auf geschützte Mitglieder.Klon ist eine schlechte Praxis, und Ihre Frage ist der Grund für das (Unterklasse Klonen).
In der Regel sollten Sie nur verwenden, kopieren cotrs statt und haben die Unterklasse akzeptieren ein Elternteil als parameter.
public Base(){}
public Base(Base pSource){}
public Sub(){}
public Sub(Base pSource, weitere Parameter...){}
public Sub(Sub pSource){}