4

インターフェイスを使用してオブジェクトを複製したいのですが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()));
        });
    }
4

5 に答える 5

5

キャストを囲む括弧が正しくありません。それは読むべきです

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

(ちなみに: なぜ .ForEach() ?

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

仕事もします。)

于 2010-11-07T20:48:31.510 に答える
3

他の人が言ったように、インターフェイスを明示的に実装しました。私が行うことは、クローンメソッドのタイプセーフバージョンを返す別のメソッドを作成することなので、含める傾向があります。

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

明示的に実装された clone メソッドを次のように変更します (public 修飾子は削除する必要があります)...

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

この方法では、オブジェクトから実際の型にキャストする必要はありません。

ただし、ICloneable にはいくつかの問題があります。

  • クローンが深いクローンか浅いクローンかがわからない
  • 派生クラスがそれ自体を複製するメカニズムを提供する必要があります。これは、仮想メソッドを介して行うことができます。派生型で適切なクローンを作成できない場合に備えて、クラスを封印する傾向がありますが、それはアーキテクチャとニーズに基づいて決定する必要があります。
于 2010-11-07T21:00:36.513 に答える
1

メソッドのみを呼び出す必要があります

public object Clone()

編集:
またはあなたのメソッドを呼び出します

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

ご注意おまけをつけ()ます。

于 2010-11-07T20:47:06.223 に答える
0

行は読む必要があります

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

ただし、GeoInfoクラスで明示的なインターフェイス実装を使用しないことを検討してください (例はとにかくコンパイルしないでください)。

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

次に、簡単に行うことができます

GeoInfos.Add((GeoInfo)item.Clone());
于 2010-11-07T20:48:40.403 に答える
0

メソッドを呼び出す前にICloneable.Cloneオブジェクトをキャストする必要がある明示的に実装しました。ICloneable

MSDN の明示的なインターフェイスの実装を参照してください。

オブジェクトで呼び出し可能なメソッドが必要な場合は、メソッド宣言を次のように変更します。

public object Clone()

または、静的型チェックを維持したい場合は、現在の実装をそのままにして、次を追加します。

public GeoInfo Clone()
{
    return ((ICloneable)this).Clone();
}
于 2010-11-07T20:49:25.243 に答える