Pregunta

I desea clonar un objeto con el uso de la interfaz de ICloneable y por alguna razón no puedo clonar en mi programa. Aquí está mi código:

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;
    }

}

Dentro de otra clase cuando estoy tratando de utilizar el método Clone(), por alguna razón, el compilador no puede encontrar el método. Aquí está mi otro método que está tratando de clonar:

public InfoLayer(string LayerName,List<GeoInfo> oldGeoInfos)
    {
        this.LayerName = LayerName;
        this.GeoInfos = new List<GeoInfo>();
        oldGeoInfos.ForEach((item) =>
        {
            GeoInfos.Add((GeoInfo)((ICloneable)item.Clone()));
        });
    }
¿Fue útil?

Solución

Los paréntesis alrededor de su elenco no son correctos. Se debería leer

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

(Por cierto: ¿Por qué la .ForEach ()

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

hace el trabajo también.)

Otros consejos

Como otros han dicho que ha implementado la interfaz explicitly.What lo que hago es crear otro método que devuelve una versión de seguridad de tipos del método clone por lo que tienden a incluir.

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

y cambiar el método clone explícitamente implementado a ser (el modificador público debe ser retirado) ...

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

De esta manera usted no tiene que fundido de un objeto al tipo real.

Sin embargo, hay una serie de dificultades con ICloneable:

  • No sé si el clon debe ser un profunda o superficial clon
  • Usted tiene que proporcionar un mecanismo para que las clases derivadas para clonar sí que se puede tratar de hacerlo a través de métodos virtuales. Tiendo a sellar mis clases en los casos que no puedo garantizar la clonación apropiado en los tipos derivados, pero que es una decisión que debe tomarse en torno a su architcture y necesidades.

Sólo debe llamar a su método

public object Clone()

Editar
O llame a su método

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

() nota adicional.

La línea debe leer

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

Sin embargo, tener en cuenta en su clase GeoInfo a no utilizar la implementación de interfaz explícita (el ejemplo no debe recopilar todos modos), para que se lea:

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

A continuación, puede hacer

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

Se han implementado ICloneable.Clone explícitamente, lo que requiere que el objeto se convierte al ICloneable antes de la caña de método se llama.

explícita de interfaces Implementación en MSDN.

Si desea que el método se puede llamar en el objeto, cambie la declaración del método a:

public object Clone()

Como alternativa, si desea mantener la comprobación de tipos estáticos, deje su implementación actual tal y como son y añada el siguiente:

public GeoInfo Clone()
{
    return ((ICloneable)this).Clone();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top