Warum sollte ich ICloneable in c # implementieren?
-
22-08-2019 - |
Frage
Können Sie mir erklären, warum ich von ICloneable
erben sollte und die Clone()
Methode implementieren?
Wenn ich eine tiefe Kopie tun will, kann ich nicht implementieren nur meine Methode? Sagen wir MyClone()
?
Warum sollte ich von ICloneable
erben? Was sind die Vorteile? Ist es nur eine Frage der Herstellung Code „lesbare“?
Lösung
Sie sollten nicht. Microsoft empfiehlt gegen ICloneable
Implementierung, da es von der Schnittstelle keine klare Angabe ist, ob Ihre Clone
Methode einen „tief“ oder „flach“ Klon führt.
Siehe diese Blog-Post von Brad Abrams zurück 2003 (!) für weitere Informationen.
Andere Tipps
Die ICloneable
Schnittstelle von selbst ist nicht sehr nützlich, die, dass es wirklich zu sagen, ist es nicht viele Situationen, in denen es sinnvoll zu wissen, dass ein Objekt klonbar ist, ohne etwas anderes darüber zu wissen. Dies ist eine ganz andere Situation von z.B. IEnumerable
oder IDisposable
; es gibt viele Situationen, in denen es sinnvoll ist eine IEnumerable
zu akzeptieren, ohne etwas anderes als zu wissen, wie es aufzuzählen.
Auf der anderen Seite kann ICloneable
nützlich sein, wenn sie als generische Einschränkung zusammen mit anderen Bedingungen angewendet. Zum Beispiel könnte eine Basisklasse zweckmäßigerweise eine Reihe von Derivaten unterstützen, von denen einige nutzbringend geklont werden könnten, und von denen einige nicht konnte. Wenn der Basistyp selbst einen öffentliches Klonen Schnittstelle freigelegt, dann jeder Derivat-Typ, die nicht geklont werden könnte, würde das Liskov Substitutionsprinzip verstoßen. Die Art und Weise, dieses Problem zu vermeiden, ist der Basistyp Unterstützung haben Klonen eines Geschützte Methode verwenden, und ermöglichen abgeleiteten Typen eine öffentliche Klonen Schnittstelle zu implementieren, wie sie für richtig halten.
Sobald das erreicht wurde, ein Verfahren, das ein Objekt eines WonderfulBase
Typs akzeptieren will und muss in der Lage sein, es zu klonen, codiert werden, um ein WonderfulBase Objekt zu akzeptieren, die das Klonen unterstützt (unter Verwendung eines generischen Typparameters mit Base- Art und ICloneable
constraints). Obwohl die ICloneable
Schnittstelle nicht selbst tief oder flach Klonen zeigen, würde die Dokumentation für WonderfulBase
angeben, ob klonbar WonderfulBase
tief- oder flach geklont werden soll. Im Wesentlichen würde die ICloneable
Schnittstelle nicht alles erreichen, die nicht durch die Definition ICloneableWonderfulBase
erreicht werden würde, mit der Ausnahme, dass es mit vermeiden würde für jede unterschiedliche klonbar Basisklasse unterschiedliche Namen zu definieren.
ICloneable
ist eines dieser Artefakte im BCL, die umstritten war. Es gibt keinen wirklichen Grund, IMHO, sie umzusetzen. Mit diesem wird gesagt, wenn ich eine Klon-Methode erstellen werde dann ICloneable
ich implementieren tun, und ich biete meine eigene starke typisierte Version von Clone
.
Das Problem mit ICloneable
wird nie angezeigt, wenn Clone
eine flache oder eine tiefe Kopie war die sehr verschiedene Dinge. Die Tatsache, dass es keine ICloneable<T>
könnte ein Hinweis auf Microsofts Gedanken über ICloneable sein
Matt richtig ist, verwenden Sie es nicht. Erstellen Sie Ihre eigenen Copy()
Methode (oder einem ähnlichen Namen) und machen es vollkommen klar in Ihrem öffentlichen API, ob die Methode eine tiefe oder flache Kopie des Objekts erstellt wird.