TheDeveloperBlog.com

Home | Contact Us

C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML

C# Clone Method: Object

This C# article implements the ICloneable interface and calls the Clone method. It references Framework Design Guidelines.

Clone. In science fiction movies cloning is a common plot.

It usually ends badly. And in the C# language, the Clone method and ICloneable interface are available. But using these features is confusing and not recommended.

Interface

Example. This program does the opposite of what is recommended. It uses Clone, on a string array. The Array type implements ICloneable and the Clone call results in a copied array. When we change the cloned array, the original is unchanged.

String Array

C# program that uses Clone

using System;

class Program
{
    static void Main()
    {
	string[] array = { "dot", "net", "deves" };
	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,deves
dot,net,deves

dot,net,deves
element,net,deves

In this example, we used an as-cast to change the type of the reference returned by Clone. This is needed because Clone returns an object. An explicit cast, such as (string[]), could instead be used.

AsCasts

Example 2. Next we consider the implementation of Clone. In the IL of the above program, the Array.Clone static method is called. In mscorlib, where System.Array resides, Array.Clone calls into MemberwiseClone.

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()

Also, System.Array implements the System.ICloneable interface. This is how the virtual execution engine knows to pass a call to Clone to the System.Array type. The Clone method is abstract and virtual.

IL

System.ICloneable interface: IL

.method public hidebysig newslot abstract virtual
	instance object  Clone() cil managed
{
} // end of method ICloneable::Clone

Example 3. You must never run this example code. It does something that is not recommended—it implements ICloneable. The Rock class implements ICloneable, and defines the Clone() public method.

Next: We create a new instance of the Rock class with its public constructor. We pass three arguments to it.

Public Constructor

Finally: We invoke the Clone method on the first Rock instance and cast its result. We call Console.WriteLine—this calls ToString.

Console.WriteLineToString

C# 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

Discussion. As noted in Framework Design Guidelines, Clone has some problems. The main issue is the question of shallow and deep copies. ICloneable does not define which kind of cloning is done.

So: The developers using Clone are left guessing. This negates the whole point of interfaces, which is to define contracts.

And: This makes using ICloneable and Clone almost as problematic as cloning in science fiction movies. Framework design guidelines.

The contract of ICloneable does not specify the type of clone implementation required to satisfy the contract.... 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

Summary. We explored the Clone method and ICloneable interface. It is hard to use this interface correctly. In may be impossible to use correctly, due to a weakness in its contract. Instead using custom methods is perhaps clearer.


Related Links

Adjectives Ado Ai Android Angular Antonyms Apache Articles Asp Autocad Automata Aws Azure Basic Binary Bitcoin Blockchain C Cassandra Change Coa Computer Control Cpp Create Creating C-Sharp Cyber Daa Data Dbms Deletion Devops Difference Discrete Es6 Ethical Examples Features Firebase Flutter Fs Git Go Hbase History Hive Hiveql How Html Idioms Insertion Installing Ios Java Joomla Js Kafka Kali Laravel Logical Machine Matlab Matrix Mongodb Mysql One Opencv Oracle Ordering Os Pandas Php Pig Pl Postgresql Powershell Prepositions Program Python React Ruby Scala Selecting Selenium Sentence Seo Sharepoint Software Spellings Spotting Spring Sql Sqlite Sqoop Svn Swift Synonyms Talend Testng Types Uml Unity Vbnet Verbal Webdriver What Wpf