我想使用一个对象使用 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()));
        });
    }
有帮助吗?

解决方案

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

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

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

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

也做这项工作。)

其他提示

正如其他人所说的那样,您已经明确地实现了接口。我要做的就是创建另一种返回克隆方法的typesafe版本的方法,因此我倾向于包含。

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

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

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

这样,您就不必从对象施放到真实类型。

但是,有很多难以忍受的困难:

  • 您不知道克隆是否应该是 深或浅克隆
  • 您必须提供一种派生类的机制来克隆本身,您可以尝试通过虚拟方法进行操作。在情况下,我倾向于密封我的课程,我无法确保在派生类型中进行适当的克隆,但这是根据您的架构和需求做出的决定。

您只应该调用您的方法

public object Clone()

编辑:
或致电您的方法

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

注意额外 ().

该行必须阅读

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

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

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

那你可以简单地做

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

您已经实施了 ICloneable.Clone 明确地,这要求对象被施加到 ICloneable 在调用甘蔗之前。

显式接口实现 在MSDN上。

如果要在对象上可调用该方法,请将方法声明更改为:

public object Clone()

另外,如果要保持静态类型检查,请将当前的实现如下,并添加以下内容:

public GeoInfo Clone()
{
    return ((ICloneable)this).Clone();
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top