Замена абстрактного свойства производным возвращаемым типом в C #

У меня четыре класса. Запрос, DerivedRequest, Обработчик, DerivedHandler. У класса Handler есть свойство со следующим объявлением:

public abstract Request request { get; set; }

DerivedHandler должен переопределить это свойство, чтобы вместо этого он возвращал DerivedRequest:

public override DerivedRequest request { get; set; }

Есть ли у кого-нибудь идеи о том, как заставить это работать?

30
задан Trevor 14 June 2011 в 22:42
поделиться

3 ответа

Это не очень хороший способ структурировать вещи. Выполните одно из следующих действий

1) Просто не меняйте тип возвращаемого значения и обычно переопределяйте его в подклассе. В DerivedHandler вы можете вернуть экземпляр DerivedRequest, используя сигнатуру базового класса Request. Любой клиентский код, использующий это, может при желании привести его к DerivedRequest.

2) Вместо этого используйте дженерики, если они не должны быть полиморфными.

public abstract class HandlerBase<T> where T: Request
{
    public abstract T Request {get;set;}
}

public class Handler: HandlerBase<Request>()

public class DerivedHandler: HandlerBase<DerivedRequest>()
18
ответ дан 28 November 2019 в 00:21
поделиться

За исключением сокрытия первоначального свойства:

public new DerivedRequest Request { get;set;}

Однако я настоятельно рекомендую против этого. Скрытие чего-то, что должно быть переопределено, создает проблемы, особенно если свойство не является простым автоматически сгенерированным. Также, если использовать его в качестве интерфейса или базового класса, исходную реализацию (в этом случае на один класс выше в дереве наследования). Если вы реализуете абстрактный класс или интерфейс, вы даже не сможете скрыть оригинальную подпись, так как вам необходимо ее реализовать.

Обычно, если вы думаете об использовании ключевого слова new, вы на неправильном пути. Есть случаи, когда это необходимо и необходимо, однако в большинстве случаев это не так.

Вместо этого создайте еще одно свойство:

public DerivedRequest DerivedRequest {/* make adequate conversions here*/ }

Таким образом, вы будете в курсе ООП, и вы получите свою информацию в понятном виде.

5
ответ дан 28 November 2019 в 00:21
поделиться

Это теоретически невозможно. Переопределение должно быть ковариантным для типа возвращаемого значения (то есть тип возвращаемого значения должен быть более конкретным или одинаковым) и противоположным для параметра (то есть тип параметра должен быть менее конкретным или одинаковым). Таким образом, ваш новый тип должен быть одновременно одновременно ковариантным и контравариантным по отношению к Request - это означает, что единственный возможный тип - это просто Request.

По этой причине в C # не разрешается изменять тип свойств для переопределений.

0
ответ дан 28 November 2019 в 00:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: