Por que devo implementar ICloneable em c #?

110

Você pode me explicar por que devo herdar ICloneablee implementar o Clone()método?

Se eu quiser fazer uma cópia profunda, não posso simplesmente implementar meu método? Vamos dizer MyClone()?

Por que devo herdar ICloneable? Quais são as vantagens? É apenas uma questão de tornar o código "mais legível"?

uinc
fonte

Respostas:

29

A ICloneableinterface por si só não é muito útil, o que quer dizer que realmente não existem muitas situações em que seja útil saber que um objeto pode ser clonado sem saber mais nada sobre ele. Esta é uma situação muito diferente de, por exemplo, IEnumerableou IDisposable; há muitas situações em que é útil aceitar um IEnumerablesem saber nada além de como enumerá-lo.

Por outro lado, ICloneablepode ser útil quando aplicado como uma restrição genérica junto com outras restrições. Por exemplo, uma classe base pode suportar de forma útil uma série de derivados, alguns dos quais podem ser clonados de forma útil e outros não. Se o próprio tipo base expusesse uma interface de clonagem pública, então qualquer tipo derivado que não pudesse ser clonado violaria o Princípio de Substituição de Liskov. A maneira de evitar esse problema é fazer com que o tipo base suporte a clonagem usando um método Protected e permitir que os tipos derivados implementem uma interface de clonagem pública conforme acharem adequado.

Uma vez feito isso, um método que deseja aceitar um objeto de um WonderfulBasetipo, e precisa ser capaz de cloná-lo, pode ser codificado para aceitar um objeto WonderfulBase que suporte a clonagem (usando um parâmetro de tipo genérico com tipo base e ICloneablerestrições) . Embora a própria ICloneableinterface não indique clonagem profunda ou superficial, a documentação para WonderfulBaseindicaria se clonável WonderfulBasedeve ser clonado profunda ou superficial. Essencialmente, a ICloneableinterface não realizaria nada que não seria realizado pela definição ICloneableWonderfulBase, exceto que evitaria a necessidade de definir nomes diferentes para cada classe base clonável diferente.

supergato
fonte
18

ICloneableé um daqueles artefatos no BCL que tem sido controverso. Não há razão real para a IMHO implementá-lo. Com isso dito, se eu vou criar um método clone, eu o implemento ICloneablee forneço minha própria versão de tipo forte Clone.

O problema com ICloneableé que nunca Clonefoi indicado se era uma cópia superficial ou profunda, que são coisas muito diferentes. O fato de não haver ICloneable<T>pode haver uma indicação nas idéias da Microsoft sobre o ICloneable

JoshBerke
fonte
9

Matt está correto, não o use. Crie seu próprio Copy()método (ou nome semelhante) e deixe perfeitamente claro em sua API pública se seu método está criando uma cópia profunda ou superficial de seu objeto.

John Rasch
fonte