题
我想使用一个对象使用 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();
}
不隶属于 StackOverflow