Cloning
The .NET runtime offers a quick and easy method for shallow cloning with object.MemberwiseClone
. However, deeply cloning an object tree usually involves a lot of repetitive code, which can add both cost and bugs to your application. This is one of the many patterns you can fully automate with Metalama.
To make an object deeply clonable, you typically need to:
- Implement the
ICloneable
interface for the type. - Add a method
public T Clone()
and implement it, usually by callingMemberwiseClone
and then invoking theClone
method on each field of a clonable type. - Implement
object ICloneable.Clone()
as an explicit interface implementation, which calls the publicClone
method.
Most of the time, this is purely algorithmic work.
Example
The Cloneable example aspect covers all the steps mentioned above, and more. It requires you to mark the fields you wish to clone with the [Child]
custom attribute, but feel free to modify the aspect code to change this behavior.
You can apply this to any class:
[Cloneable]
class Game
{
public Player Player { get; set; }
[Child]
public GameSettings Settings { get; set; }
}
During compilation, the following code will be generated:
using System;
[Cloneable]
class Game
: ICloneable
{
public Player Player { get; set; }
[Child]
public GameSettings Settings { get; set; }
public virtual Game Clone()
{
var clone = (Game)this.MemberwiseClone();
clone.Settings = ((GameSettings)this.Settings.Clone());
return clone;
}
object ICloneable.Clone()
{
return Clone();
}
}
If you make the class partial
, Metalama will also generate the code at design time. This means that Intellisense will “see” that Game
implements ICloneable
and includes a public Clone
method.
Resources
- Commented example: Deep Cloning