繁体   English   中英

在C#中克隆一个对象

[英]cloning an object in C#

我想使用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();

做的也很好。)

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

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

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

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

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

然而,ICloneable存在许多困难:

  • 您不知道克隆是深层还是浅层克隆
  • 您必须为派生类提供一种机制来克隆自己,您可以尝试通过虚拟方法执行此操作。 我倾向于密封我的课程,因为我无法确保在派生类型中进行适当的克隆,但这是根据您的结构和需求做出的决定。

你应该只调用你的方法

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 ,这要求在调用方法甘蔗之前将对象ICloneableICloneable

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

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

public object Clone()

或者,如果要保留静态类型检查,请按原样保留当前实现,并添加以下内容:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM