At attempt to copy object b the object a is copied

using System; public interface IClonable{ object Clone(); } public class Array:IClonable{ int size; int[] ptr = {}; public object Clone() { return new Array { size = this.size, ptr = this.ptr }; } public Array(){ size = 3; ptr = new int[size]; for(int ix=0; ix<size; ix++){ ptr[ix]=ix; Console.WriteLine(ptr[ix]); } } public Array(int size){ this.size = size; ptr = new int[size]; for(int ix=0; ix<size; ix++){ ptr[ix]=ix; Console.WriteLine(ptr[ix]); } } } public class Test { public static void Main() { Array a = new Array(); Array b = new Array(5); Array c = (Array)b.Clone(); } } 
  • Why did you decide that object a being copied? - Grundy
  • ptr = this.ptr is not cloning. - Qwertiy
  • @Grundy, because it has output only in constructors. - Qwertiy
  • and how to clone ptr - asasda
  • You need to pass at least something to the clone method. You get that inside the clone method (size = this.size) - the size field is equal to itself. ptr [] is an array, you need to clone it accordingly, passing an object with an array and using the appropriate command (cloning for an array) - Garrus_En

3 answers 3

 return new Array { size = this.size, ptr = this.ptr }; 

This is actually

 var res = new Array(); res.size = this.size; res.ptr = this.ptr; return res; 

And the output is only inside the constructor, and the constructor is called without parameters.

 ptr = this.ptr 

And this is not cloning at all - there is also an array.

  • Why then in the object "c" all the properties of the object "a" - asasda
  • because in this case objects c and a are links to the same instance of an object in memory - Garrus_En
  • one
    @Garrus_En, you're wrong - Grundy

If I bring your code to a working view, then it turned out to be similar to that of Qwertiy, with only a few changes (so that the Clone method takes no arguments and returns an object).

 using System; public interface IClonable { object Clone(); } public class Array : IClonable { public int size; public int[] ptr; public Array() { this.size = 3; ptr = new int[size]; for (int i = 0; i < size; i++) { ptr[i] = i; } } public Array(int size) { this.size = size; ptr = new int[size]; for (int i = 0; i < size; i++) { ptr[i] = i; } } public object Clone() { // копирую поэлементно массив int[] clone_ptr = new int[this.size]; for (int i = 0; i < this.size; i++) { clone_ptr[i] = this.ptr[i]; } // возвращаю копию return new Array() { size = this.size, ptr = clone_ptr}; } public void Print() { for (int i = 0; i < ptr.Length; i++) { Console.Write(ptr[i] + " "); } Console.WriteLine("\n"); } } public class Test { public static void Main() { Array a = new Array(); a.Print(); Array b = new Array(5); b.Print(); Array c = (Array)b.Clone(); c.Print(); Console.ReadKey(); } } 

Here you need to make some reservations about what is done and why:

  1. size and ptr are made public to access them in this line. return new MyArray () {size = this.size, ptr = clone_ptr};
  2. to copy an array correctly, you need to do it element by element or via Array.Copy (), but the second option is impossible due to the fact that your class is also called (yes, it’s better to rename it, then Array.Copy () can be used and many more);
  3. outputting arrays in the constructor leads to confusion and problems, therefore it is better to make a method for output, for example, Print;

    It should be done like this:

     public class MyArray { int size; int[] ptr; public MyArray() { this.size = 3; ptr = new int[size]; for (int i = 0; i < size; i++) { ptr[i] = i; } } public MyArray(int size) { this.size = size; ptr = new int[size]; for (int i = 0; i < size; i++) { ptr[i] = i; } } public void myClone(MyArray array) { ptr = new int[array.size]; Array.Copy(array.ptr, this.ptr, array.size); } public void Print() { for (int i = 0; i < ptr.Length; i++) { Console.Write(ptr[i] + " "); } Console.WriteLine("\n"); } } 

    Call in the program as you planned

     class Program { static void Main(string[] args) { MyArray a = new MyArray(); MyArray b = new MyArray(8); Console.WriteLine("Массив А"); a.Print(); Console.WriteLine("Массив Б"); b.Print(); // Клонируем b в a a.myClone(b); Console.WriteLine("Массив А после клонирования"); a.Print(); Console.Read(); } } 

    Now the Copy method for the array is called, and everything is logically correct.