Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cloning an object in C#

Tags:

c#

icloneable

I want to clone an object with using the ICloneable interface and for some reason I can't clone in my program. Here is my code:

public class GeoInfo : ICloneable
{
    private long InfoID;
    private string InfoName;
    private Location InfoLocation;
    private string Description;
    private InfoTypes InfoType;
    public GeoInfo(long InfoID)
    {

        this.InfoID = InfoID;
    }
    public GeoInfo(long InfoID, Location InfoLocation):this(InfoID)
    {
        this.InfoLocation = InfoLocation;
    }
    public GeoInfo(long InfoID, string InfoName, Location InfoLocation, string Description, InfoTypes InfoType):this(InfoID,InfoLocation)
    {
        this.InfoName = InfoName;
        this.Description = Description;
        this.InfoType = InfoType;
    }
    public object ICloneable.Clone()
    {
        GeoInfo toReturn = new GeoInfo(InfoID, InfoName, InfoLocation, Description, InfoType);
        return (object)toReturn;
    }

}

Inside another class when I am trying to use the Clone() method, for some reason the compiler can't find the method. Here is my other method that is trying to Clone:

public InfoLayer(string LayerName,List<GeoInfo> oldGeoInfos)
    {
        this.LayerName = LayerName;
        this.GeoInfos = new List<GeoInfo>();
        oldGeoInfos.ForEach((item) =>
        {
            GeoInfos.Add((GeoInfo)((ICloneable)item.Clone()));
        });
    }
like image 641
Nadav Avatar asked Jan 22 '23 03:01

Nadav


2 Answers

The parentheses around your cast are not correct. It should read

GeoInfos.Add((GeoInfo)((ICloneable)item).Clone());

(By the way: Why the .ForEach() ?

this.GeoInfos = oldGeoInfos.Select(item => ((GeoInfo)((ICloneable)item.Clone()))).ToList();

does the job as well.)

like image 142
TeaDrivenDev Avatar answered Jan 31 '23 15:01

TeaDrivenDev


As others have said you have implemented the interface explicitly.What I do is create another method that returns a typesafe version of the clone method so I tend to include.

public GeoInfo Clone()
{
    return new GeoInfo(InfoID, InfoName, InfoLocation, Description, InfoType);
}

and change the explicity implemented clone method to be (the public modifier should be removed)...

object ICloneable.Clone()
{
    return Clone();  //will call the public method as above
}

This way you don't have to cast from an object to the real type.

However there are a number of difficulties with ICloneable:

  • You don't know if the clone should be a deep or shallow clone
  • You have to provide a mechanism for derived classes to clone itself which you can attempt to do via virtual methods. I tend to seal my classes in cases I cannot ensure proper cloning in derived types but that is a decision to be made based around your architcture and needs.
like image 20
aqwert Avatar answered Jan 31 '23 17:01

aqwert