简体   繁体   English

在C#中克隆一个对象

[英]cloning an object in C#

I want to clone an object with using the ICloneable interface and for some reason I can't clone in my program. 我想使用ICloneable接口克隆一个对象,由于某种原因我不能克隆我的程序。 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 am trying to use the Clone() method, for some reason the compiler can't find the method. 当我尝试使用Clone()方法时,在另一个类中,由于某种原因,编译器无法找到该方法。 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()));
        });
    }

The parentheses around your cast are not correct. 你的演员周围的括号不正确。 It should read 它应该读

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

(By the way: Why the .ForEach() ? (顺便说一句:为什么.ForEach()?

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

does the job as well.) 做的也很好。)

As others have said you have implemented the interface explicitly.What I do is create another method that returns a typesafe version of the clone method so I tend to include. 正如其他人所说,你已经明确地实现了接口。我所做的是创建另一个方法,返回克隆方法的类型安全版本,所以我倾向于包含。

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

and change the explicity implemented clone method to be (the public modifier should be removed)... 并将明确实现的克隆方法更改为(应删除公共修饰符)...

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

This way you don't have to cast from an object to the real type. 这样您就不必从对象转换为实际类型。

However there are a number of difficulties with ICloneable: 然而,ICloneable存在许多困难:

  • You don't know if the clone should be a deep or shallow clone 您不知道克隆是深层还是浅层克隆
  • You have to provide a mechanism for derived classes to clone itself which you can attempt to do via virtual methods. 您必须为派生类提供一种机制来克隆自己,您可以尝试通过虚拟方法执行此操作。 I tend to seal my classes in cases I cannot ensure proper cloning in derived types but that is a decision to be made based around your architcture and needs. 我倾向于密封我的课程,因为我无法确保在派生类型中进行适当的克隆,但这是根据您的结构和需求做出的决定。

You should only call your method 你应该只调用你的方法

public object Clone()

Edit: 编辑:
Or call your method 或者打电话给你的方法

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

note extra () . 注意额外()

The line must read 该行必须阅读

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

But consider in your GeoInfo class to not use explicit interface implementation (your example shouldn't compile anyway), so that it reads: 但是请考虑在你的GeoInfo类中不使用显式接口实现(你的例子不应该编译),所以它读取:

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

Then you can simply do 然后你就可以做到

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

You have implemented ICloneable.Clone explicitly, which requires that the object is cast to ICloneable before the method cane be called. 您已明确实现了ICloneable.Clone ,这要求在调用方法甘蔗之前将对象ICloneableICloneable

See Explicit Interface Implementation on MSDN. 请参阅MSDN上的显式接口实现

If you want the method callable on your object, change the method declaration to: 如果希望对象上的方法可调用,请将方法声明更改为:

public object Clone()

Alternatively, if you want to keep static type checking, leave your current implementation as-is, and add the following: 或者,如果要保留静态类型检查,请按原样保留当前实现,并添加以下内容:

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

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

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