Home > Software design >  How can I copy/clone objects(reference type) without using IClonable in C#?
How can I copy/clone objects(reference type) without using IClonable in C#?

Time:12-24

I don't want to assign properties one by one. Please do not say, I need to assign 1 by 1. I know IClonable interface but unfortunately, suppose that Point class comes from other library , so I can not modify. How can I achieve cloning object which belongs to other libraries?

In below example, as expected when we change p2, p1 is changed as well. My aim is copying p1, and when I change copy object, I do not want main object to change. Int his example, I want p1 to keep as it was before.

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");

        Point p1 = new Point(5,6);
        Point p2= p1;

        p2.X = 9;

        Console.WriteLine("x={0}, y={1}", p1.X, p1.Y);
    }

    class Point 
    {
       // Constructor:
       public Point(int x, int y)
       {
          X = x;
          Y = y;
       }

       // Property implementation:
       public int X { get; set; }

       public int Y { get; set; }
    }
}

CodePudding user response:

You can use the MemberwiseClone method inherited from System.Object:

public Point ShallowClone()
{
   return (Point)this.MemberwiseClone();
}

ICloneable is an interface, not a class. Whether you implement ICloneable or not makes no difference regarding assign properties one by one or not.


Other options:

  • If you have not access to the code of Point or cannot derive your implementation from it:
    • Use the AutoMapper NuGet package (or one of the various other ones).
    • Create an extension method.
  • Make the class immutable. Like this you can just copy the reference around just as with strings.
  • Implement Point as a struct. Structs can be copied by simple assignment.
  • Implement Point as a class or struct record which automatically provides value behavior (immutability, value equality) and much more. See: Records (C# reference).

CodePudding user response:

I sorted out this problem with using automapper .

You can check my solution:

https://dotnetfiddle.net/En51IP (using new way )

https://dotnetfiddle.net/iapj84 (using old way )

  • Related