Frage

Ich möchte ein Objekt klonen mit der ICloneable Schnittstelle und aus irgendeinem Grunde kann ich nicht in meinem Programm klonen. Hier ist mein 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;
    }

}

innerhalb einer anderen Klasse, wenn ich versuche, die Clone() Methode zu verwenden, aus irgendeinem Grund der Compiler die Methode nicht finden können. Hier ist meine andere Methode, die zu klonen versucht:

public InfoLayer(string LayerName,List<GeoInfo> oldGeoInfos)
    {
        this.LayerName = LayerName;
        this.GeoInfos = new List<GeoInfo>();
        oldGeoInfos.ForEach((item) =>
        {
            GeoInfos.Add((GeoInfo)((ICloneable)item.Clone()));
        });
    }
War es hilfreich?

Lösung

Die Klammern um Ihre Güsse sind nicht korrekt. Es sollte lesen

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

(übrigens: Warum die .ForEach ()

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

macht den Job auch.)

Andere Tipps

Wie schon andere gesagt haben, Sie haben implementiert die Schnittstelle explicitly.What ich tun, ist eine andere Methode erstellen, dass die Renditen eine typsichere Version des Klon-Methode so neige ich dazu gehören.

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

und ändern Sie die explicity implementiert Klon-Methode (der öffentliche Modifikator sollte entfernt werden) ...

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

Auf diese Weise haben Sie nicht von einem Objekt zu gegossenen die realen Art.

Es gibt jedoch eine Reihe von Schwierigkeiten mit ICloneable:

  • Sie wissen nicht, ob der Klon ein sein sollte tief oder flach Klon
  • Sie haben einen Mechanismus für abgeleitete Klassen zur Verfügung zu stellen Klon selbst, die Sie versuchen können, über virtuelle Methoden zu tun. Ich neige dazu, meine Klassen in Fällen versiegeln kann ich nicht richtig Klonen in abgeleiteten Typen sicherzustellen, aber das ist eine Entscheidung auf Basis Ihre architcture und Bedürfnisse gemacht werden.

Sie sollten nur rufen Sie Ihre Methode

public object Clone()

Bearbeiten
Oder rufen Sie Ihre Methode

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

note zusätzliche ().

Die Zeile lesen muss

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

Aber betrachten Sie in Ihrer GeoInfo Klasse nicht explizite Schnittstellenimplementierung verwenden (Ihr Beispiel soll nicht kompiliert sowieso), so dass es lautet:

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

Dann können Sie einfach tun

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

Sie haben explizit implementiert ICloneable.Clone, das erfordert, dass das Objekt zu ICloneable, bevor die Methode Rohr gegossen wird, genannt werden.

Siehe Explizite Schnittstellenimplementierung auf MSDN.

Wenn Sie die Methode aufrufbar auf Ihrem Objekt wollen, ändern Sie die Methode Erklärung:

public object Clone()

Wenn Sie alternativ statische Typprüfung behalten wollen, lassen Sie Ihre aktuelle Implementierung, wie sie ist, und fügen Sie die folgende:

public GeoInfo Clone()
{
    return ((ICloneable)this).Clone();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top