Возможно ли иметь базовый класс с типом возврата, который подстраивается под тип базового класса? - PullRequest
0 голосов
/ 08 августа 2009

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

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

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

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

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

Ответы [ 2 ]

3 голосов
/ 08 августа 2009

Что ж, 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, что обычно очень удобно. Если вам это не нужно, вы можете потерять ограничение.

0 голосов
/ 08 августа 2009

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

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

public class MyDerived : MyBase<MyDerived>
{
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...