Cloning an object in C #

I want to clone an object using the ICloneable interface and for some reason I cannot 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 try to use the Clone() method, for some reason, the compiler cannot 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())); }); } 
+4
source share
5 answers

The brackets around your throw are incorrect. He must read

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

(By the way: why .ForEach ()?

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

also does the work.)

+5
source

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

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

and change the exclusion cloning method used (public modifier must be removed) ...

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

This way you do not need to cast from an object into a real type.

However, with ICloneable there are a number of difficulties:

  • You don’t know if the clone should be a deep or shallow clone
  • You must provide a mechanism for cloned derived classes, which you can try to make using virtual methods. I tend to seal my classes in cases where I cannot provide the correct cloning in derived types, but this is a decision that should be made based on your architecton and needs.
+3
source

You should only call your method

 public object Clone() 

Edit:
Or call your method

 oldGeoInfos.ForEach((item) => { GeoInfos.Add((GeoInfo)(((ICloneable)item).Clone())); }); 

mark optional () .

+1
source

The string should read

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

But consider in your GeoInfo class not to use an explicit interface implementation (your example should not compile anyway) so that it reads:

 public object Clone() { //... } 

Then you can just do

 GeoInfos.Add((GeoInfo)item.Clone()); 
0
source

You have implemented ICloneable.Clone explicitly, which requires that the object be ported to ICloneable before calling the cane method.

See Explicit Interface Implementation on MSDN.

If you want the method to be called on your object, change the method declaration to:

 public object Clone() 

Alternatively, if you want to keep checking the static type, leave the current implementation as it is, and add the following:

 public GeoInfo Clone() { return ((ICloneable)this).Clone(); } 
0
source

All Articles