Возможно ли иметь базовый класс с типом возвращаемого значения, который подстраивается под тип базового класса?

StackOverflow https://stackoverflow.com/questions/1246859

  •  12-09-2019
  •  | 
  •  

Вопрос

В основном моя настройка такова:

public abstract class BaseObject{
    public abstract BaseObject Clone();
}

public class DerivedObject : BaseObject{
    public DerivedObject Clone()
    {
        //Clone logic
    }
}

Приведенный выше код не компилируется, потому что невозможно изменить возвращаемый тип при переопределении метода.

Возможно ли добиться того, чтобы метод Clone каждого производного типа возвращал аргумент своего собственного типа (возможно, через generics)?

Это было полезно?

Решение

Ну, C # не допускает ковариантных возвращаемых типов, как вы уже выяснили...но ты может используйте дженерики:

public abstract class BaseObject<T> where T : BaseObject<T>
{
    public abstract T Clone();
}

public class DerivedObject : BaseObject<DerivedObject>
{
    public override DerivedObject Clone()
    {
         // ...
    }
}

Это решение может быть затруднительным по-разному - не в последнюю очередь потому, что его трудно понять, - но оно может достаточно хорошо работать во многих ситуациях.

Редактировать:Причина, по которой я включил ограничение на T, заключается в том, что BaseObject может вызывать "свои собственные" методы в экземплярах T, что обычно очень удобно.Однако, если вам это не нужно, вы можете избавиться от ограничения.

Другие советы

Вы можете сделать что-то вроде этого.Вместо возврата default(T) верните что-нибудь, основанное на логике клонирования.

public class MyBase<T>
{
    public T Clone()
    {
        return default(T);
    }
}

public class MyDerived : MyBase<MyDerived>
{
}

Кстати, для клонирования объекта мне нравится сериализовать текущий объект в память с помощью двоичного сериализатора, а затем десериализовать эту память обратно в новый экземпляр.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top