Czy możesz mi wyjaśnić, dlaczego powinienem dziedziczyć ICloneable
i wdrożyć tę Clone()
metodę?
Jeśli chcę zrobić dokładną kopię, czy nie mogę po prostu wdrożyć mojej metody? PowiedzmyMyClone()
?
Dlaczego powinienem dziedziczyć po ICloneable
? Jakie są zalety? Czy to tylko kwestia uczynienia kodu bardziej czytelnym?
c#
.net
cloneable
icloneable
uinc
źródło
źródło
Odpowiedzi:
Nie powinieneś. Firma Microsoft odradza implementację,
ICloneable
ponieważ w interfejsie nie ma wyraźnego wskazania, czyClone
metoda wykonuje „głęboki”, czy „płytki” klon.Zobacz ten post na blogu Brada Abramsa z 2003 roku (!), Aby uzyskać więcej informacji.
źródło
ICloneable
Interfejs sama nie jest bardzo użyteczne, to znaczy, że tak naprawdę nie jest wiele sytuacji, w których warto jest wiedzieć, że obiekt jest Cloneable nie wiedząc niczego o nim. To jest sytuacja zupełnie inna niż np.IEnumerable
LubIDisposable
; jest wiele sytuacji, w których warto zaakceptować coś,IEnumerable
nie wiedząc nic poza tym, jak je wyliczyć.Z drugiej strony
ICloneable
może być przydatne, gdy jest stosowane jako ograniczenie ogólne wraz z innymi ograniczeniami. Na przykład klasa bazowa może z pożytkiem obsługiwać wiele pochodnych, z których niektóre można pożytecznie sklonować, a inne nie. Jeśli sam typ bazowy ujawniłby publiczny interfejs klonowania, to każdy typ pochodny, którego nie można było sklonować, naruszyłby zasadę zastępowania Liskova. Sposobem na uniknięcie tego problemu jest umożliwienie klonowania typu podstawowego przy użyciu metody chronionej i zezwolenie typom pochodnym na implementację publicznego interfejsu klonowania według własnego uznania.Po wykonaniu tej czynności metoda, która chce zaakceptować obiekt
WonderfulBase
typu i musi być w stanie go sklonować, mogłaby zostać zakodowana tak, aby akceptowała obiekt WonderfulBase obsługujący klonowanie (przy użyciu parametru typu ogólnego z typem bazowym iICloneable
ograniczeniami) . Chociaż samICloneable
interfejs nie wskazywałby na głębokie lub płytkie klonowanie, dokumentacjaWonderfulBase
wskazywałaby, czy klonowalnyWonderfulBase
powinien być klonowany głęboko, czy płytko. ZasadniczoICloneable
interfejs nie osiągnąłby niczego, czego nie dałoby się osiągnąć poprzez zdefiniowanieICloneableWonderfulBase
, poza tym, że uniknąłby konieczności definiowania różnych nazw dla każdej innej możliwej do klonowania klasy bazowej.źródło
ICloneable
jest jednym z tych artefaktów w BCL, który był kontrowersyjny. Nie ma prawdziwego powodu IMHO, aby to wdrożyć. Mając to na uwadze, jeśli mam zamiar utworzyć metodę klonowania, implementuję jąICloneable
i udostępniam własną silnie wpisaną wersjęClone
.Problem
ICloneable
polega na tym, że nigdy nie wskazano, czyClone
była to płytka czy głęboka kopia, które są bardzo różnymi rzeczami. Fakt, że nie ma,ICloneable<T>
może wskazywać na przemyślenia Microsoftu na temat ICloneableźródło
Matt ma rację, nie używaj go. Stwórz własną
Copy()
metodę (lub podobną nazwę) i wyjaśnij w publicznym API, czy twoja metoda tworzy głęboką, czy płytką kopię twojego obiektu.źródło