C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
Example: We use an as-cast to change the type of the reference returned by Clone. This is needed because Clone returns an object.
AsCastsC# program that uses Clone
using System;
class Program
{
static void Main()
{
string[] array = { "dot", "net", "Codex" };
string[] cloned = array.Clone() as string[];
Console.WriteLine(string.Join(",", array));
Console.WriteLine(string.Join(",", cloned));
Console.WriteLine();
// Change the first element in the cloned array.
cloned[0] = "element";
Console.WriteLine(string.Join(",", array));
Console.WriteLine(string.Join(",", cloned));
}
}
Output
dot,net,Codex
dot,net,Codex
dot,net,Codex
element,net,Codex
Clone method call: IL
IL_0022: callvirt instance object [mscorlib]System.Array::Clone()
System.Array implementation: IL
IL_0001: call instance object System.Object::MemberwiseClone()
System.ICloneable interface: IL
.method public hidebysig newslot abstract virtual
instance object Clone() cil managed
{
} // end of method ICloneable::Clone
Next: We create a new instance of the Rock class with its public constructor. We pass three arguments to it.
ConstructorFinally: We invoke the Clone method on the first Rock instance and cast its result. We call Console.WriteLine—this calls ToString.
ConsoleToStringC# program that implements ICloneable
using System;
class Rock : ICloneable
{
int _weight;
bool _round;
bool _mossy;
public Rock(int weight, bool round, bool mossy)
{
this._weight = weight;
this._round = round;
this._mossy = mossy;
}
public object Clone()
{
return new Rock(this._weight, this._round, this._mossy);
}
public override string ToString()
{
return string.Format("weight = {0}, round = {1}, mossy = {2}",
this._weight,
this._round,
this._mossy);
}
}
class Program
{
static void Main()
{
Rock rock1 = new Rock(10, true, false);
Rock rock2 = rock1.Clone() as Rock;
Console.WriteLine("1. {0}", rock1);
Console.WriteLine("2. {0}", rock2);
}
}
Output
1. weight = 10, round = True, mossy = False
2. weight = 10, round = True, mossy = False
So: The developers using Clone are left guessing. This works against the whole point of interfaces, which is to define contracts.
Quote: The contract of ICloneable does not specify the type of clone implementation required to satisfy the contract....
Quote: Consumers cannot rely on ICloneable to let them know whether an object is deep-copied or not. Therefore we recommend that ICloneable not be implemented (Framework Design Guidelines).