Вопрос

Я хочу клонировать объект с использованием 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);
}

и изменить реализованный метод клонов с явностью (общественный модификатор должен быть удален) ...

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

Таким образом, вам не нужно отбрасывать из объекта в реальный тип.

Однако есть ряд трудностей с Iclonable:

  • Вы не знаете, должен ли клон быть глубокий или мелкий клон
  • Вы должны предоставить механизм для полученных классов для клона, который вы можете попытаться сделать с помощью виртуальных методов. Я склонен запечатать свои занятия в случаях, когда я не могу обеспечить надлежащее клонирование в производных типах, но это решение, которое должно быть принято на основе вашей архитектуры и потребностей.

Вы должны позвонить только в свой метод

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();
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top