4

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

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()));
        });
    }
4

5 回答 5

5

演员表周围的括号不正确。它应该读

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

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

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

也可以完成这项工作。)

于 2010-11-07T20:48:31.510 回答
3

正如其他人所说,您已经明确实现了接口。我所做的是创建另一个方法,该方法返回克隆方法的类型安全版本,因此我倾向于包含。

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

并将显式实现的克隆方法更改为(应删除公共修饰符)...

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

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

然而,ICloneable 存在许多困难:

  • 你不知道克隆应该是深克隆还是浅克隆
  • 您必须为派生类提供一种克隆自身的机制,您可以尝试通过虚拟方法进行克隆。如果我无法确保在派生类型中正确克隆,我倾向于密封我的类,但这是根据您的架构和需求做出的决定。
于 2010-11-07T21:00:36.513 回答
1

你应该只调用你的方法

public object Clone()

编辑:
或调用您的方法

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

注意额外()

于 2010-11-07T20:47:06.223 回答
0

该行必须阅读

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

但是请考虑在您的GeoInfo类中不使用显式接口实现(您的示例无论如何都不应该编译),因此它显示为:

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

然后你可以简单地做

GeoInfos.Add((GeoInfo)item.Clone());
于 2010-11-07T20:48:40.403 回答
0

您已ICloneable.Clone显式实现,这要求在ICloneable调用方法 cane 之前将对象转换为。

请参阅MSDN 上的显式接口实现

如果您希望对象上的方法可调用,请将方法声明更改为:

public object Clone()

或者,如果您想保持静态类型检查,请保持当前实现不变,并添加以下内容:

public GeoInfo Clone()
{
    return ((ICloneable)this).Clone();
}
于 2010-11-07T20:49:25.243 回答