C# Language
ICloneable
Ricerca…
Sintassi
- oggetto ICloneable.Clone () {return Clone (); } // Implementazione privata del metodo di interfaccia che utilizza la nostra funzione pubblica personalizzata Clone ().
- pubblico Foo Clone () {return new Foo (this); } // Il metodo clone pubblico dovrebbe utilizzare la logica del costruttore di copie.
Osservazioni
Il CLR
richiede un object Clone()
definizione del metodo object Clone()
che non sia sicuro da testo. È prassi comune sovrascrivere questo comportamento e definire un metodo sicuro per tipo che restituisce una copia della classe contenente.
Spetta all'autore decidere se la clonazione significa solo copia superficiale o copia profonda. Per strutture immutabili contenenti riferimenti si consiglia di fare una copia profonda. Poiché le classi sono riferimenti a se stessi, probabilmente è meglio implementare una copia superficiale.
NOTA: In C#
un metodo di interfaccia può essere implementato privatamente con la sintassi mostrata sopra.
Implementazione ICloneable in una classe
Implementare ICloneable
in una classe con una svolta. Esporre un Clone()
tipo pubblico sicuro e implementare l' object Clone()
privatamente.
public class Person : ICloneable
{
// Contents of class
public string Name { get; set; }
public int Age { get; set; }
// Constructor
public Person(string name, int age)
{
this.Name=name;
this.Age=age;
}
// Copy Constructor
public Person(Person other)
{
this.Name=other.Name;
this.Age=other.Age;
}
#region ICloneable Members
// Type safe Clone
public Person Clone() { return new Person(this); }
// ICloneable implementation
object ICloneable.Clone()
{
return Clone();
}
#endregion
}
Successivamente sarà usato come segue:
{
Person bob=new Person("Bob", 25);
Person bob_clone=bob.Clone();
Debug.Assert(bob_clone.Name==bob.Name);
bob.Age=56;
Debug.Assert(bob.Age!=bob.Age);
}
Si noti che la modifica dell'età di bob
non modifica l'età di bob_clone
. Questo perché il design utilizza la clonazione anziché l'assegnazione di variabili (di riferimento).
Implementazione ICloneable in una struttura
L'implementazione di ICloneable per una struttura non è in genere necessaria poiché le strutture eseguono una copia membro con l'operatore di assegnazione =
. Ma il progetto potrebbe richiedere l'implementazione di un'altra interfaccia che eredita da ICloneable
.
Un altro motivo potrebbe essere se la struttura contiene un tipo di riferimento (o un array) che avrebbe bisogno anche di una copia.
// Structs are recommended to be immutable objects
[ImmutableObject(true)]
public struct Person : ICloneable
{
// Contents of class
public string Name { get; private set; }
public int Age { get; private set; }
// Constructor
public Person(string name, int age)
{
this.Name=name;
this.Age=age;
}
// Copy Constructor
public Person(Person other)
{
// The assignment operator copies all members
this=other;
}
#region ICloneable Members
// Type safe Clone
public Person Clone() { return new Person(this); }
// ICloneable implementation
object ICloneable.Clone()
{
return Clone();
}
#endregion
}
Successivamente sarà usato come segue:
static void Main(string[] args)
{
Person bob=new Person("Bob", 25);
Person bob_clone=bob.Clone();
Debug.Assert(bob_clone.Name==bob.Name);
}