class Employee : ICloneable
{
public string Name { get; set; } = string.Empty;
public int Age { get; set; }
public Employee(string name, int age)
{
Name = name;
Age = age;
}
public object Clone()
{
return new Employee(Name, Age);
}
}
class Program
{
static void Main(string[] args)
{
Employee e1 = new Employee("Ajeet", 32);
Employee e2 = (Employee)e1.Clone();
Console.WriteLine($"Name:{e1.Name}, Age:{e1.Age}");
Console.WriteLine($"Name:{e2.Name}, Age:{e2.Age}");
}
}The Clone() method creates a new Employee object and copies the values:
public object Clone()
{
return new Employee(Name, Age);
}
Since, string is immutable reference type and int is a value type, this effectively behaves like a deep enough copy for Employee class.
Example:
Employee e1 = new Employee("Ajeet", 32);
Employee e2 = (Employee)e1.Clone();
e2.Name = "Rahul";
Console.WriteLine(e1.Name); // Ajeet
Console.WriteLine(e2.Name); // Rahul
e1 remains unchanged because e2 is a different object.
Problems with ICloneable
But there are two design issues with ICloneable
1. Clone() returns object, so callers must cast:
Employee e2 = (Employee)e1.Clone();
This loses type safety.
2. ICloneable does not define shallow vs deep copy. Consumers cannot know whether:
Employee e2 = (Employee)e1.Clone();
creates shallow copy or deep copy. That ambiguity is why ICloneable is generally discouraged in modern C# APIs.
Preferred modern approach does not use ICloneable. Note that there does not exist generic ICloneable<T>. Modern C# mainly uses copy constructor or Clone method that returns specific type, which is shown in the following example.
Examples of copying object without ICloneable
Example1. Clone method returns strongly type object.
class Employee
{
public string Name { get; set; } = string.Empty;
public int Age { get; set; }
public Employee(string name, int age)
{
Name = name;
Age = age;
}
public Employee Clone()
{
return new Employee(Name, Age);
}
}
class Program
{
static void Main(string[] args)
{
Employee e1 = new Employee("Ajeet", 32);
Employee e2 = e1.Clone();
Console.WriteLine($"Name:{e1.Name}, Age:{e1.Age}");
Console.WriteLine($"Name:{e2.Name}, Age:{e2.Age}");
}
}
Example2. Copy constructorclass Employee
{
public string Name { get; set; } = string.Empty;
public int Age { get; set; }
public Employee(string name, int age)
{
Name = name;
Age = age;
}
public Employee(Employee employee)
{
this.Name = employee.Name;
this.Age = employee.Age;
}
}
class Program
{
static void Main(string[] args)
{
Employee e1 = new Employee("Ajeet", 32);
Employee e2 = new Employee(e1);
Console.WriteLine($"Name:{e1.Name}, Age:{e1.Age}");
Console.WriteLine($"Name:{e2.Name}, Age:{e2.Age}");
}
}
No comments:
Post a Comment