2010-11-07 122 views
4

我想通过使用ICloneable接口 克隆一个对象,出于某种原因,我无法在我的程序中克隆。这里是我的代码:在C中克隆一个对象#

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; 
    } 

}

里面,当我尝试使用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())); 
     }); 
    } 
+0

旁注:你可能会考虑让GeoInfos不可变,于是克隆变得不必要了。但当然,我不知道在这个具体情况下这是否可行或明智。 – CodesInChaos 2010-11-07 21:11:53

回答

5

您演员阵容的括号不正确。它应该阅读

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

(顺便说一句:?为什么.ForEach()

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

做这项工作为好)

1

您应该只叫你的方法

public object Clone() 

编辑:
或致电法

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

注额外()

0

行必须阅读

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

但考虑在你的GeoInfo类中不使用显式接口实现(你的例子不应该编译乐无论如何),所以它的内容:

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

然后,你可以简单地做

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

您已经实现ICloneable.Clone明确,这就要求该对象之前,法藤被称为转换为ICloneable

请参阅MSDN上的Explicit Interface Implementation

如果要赎回你的对象上的方法,该方法声明更改为:或者

public object Clone() 

如果您想保持静态类型检查,离开目前的实施原样,并添加以下:

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

正如其他人说你已经实现explicitly.What我做的是创造,所以我倾向于包括返回克隆方法的类型安全版本的另一种方法的接口。

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

并改变了实施的克隆方法(应该删除公共修饰符)...

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

这样,您不必从对象转换为真实类型。

但是也有许多困难与ICloneable:

  • 你不知道,如果克隆应该是一个deep or shallow clone
  • 你必须提供一种机制,派生类克隆自己,你可以试图通过虚拟方法来完成。我倾向于在我无法确保派生类型中的适当克隆的情况下封闭班级,但这是根据您的构架和需求作出的决定。