質問
使用してオブジェクトをクローンでクローンしたい 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);
}
そして、Explicity実装されたクローン法を変更するように変更します(パブリック修飾子は削除する必要があります)...
object ICloneable.Clone()
{
return Clone(); //will call the public method as above
}
これにより、オブジェクトから実際のタイプにキャストする必要はありません。
ただし、iClonableには多くの困難があります。
- クローンがaであるべきかどうかはわかりません 深いまたは浅いクローン
- 仮想メソッドを介して実行しようとすることができる派生クラスが自体をクローンするメカニズムを提供する必要があります。派生したタイプで適切にクローニングすることができない場合にクラスを封印する傾向がありますが、それはあなたの建築とニーズに基づいて行われる決定です。
メソッドのみを呼び出す必要があります
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();
}