Как передать базовый класс на стороне вызывающего и принять производное - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть служба, которая возвращает ответ базового класса. Конечно, он получил ответы.

    public class ResponseBase
    {
        public string Response { get; set; }
    }

    public class DerivedResponse : ResponseBase
    {
        public string AdditionalResponse { get; set; }
    }

Вот код службы:

public class SomeService
{
    public ResponseBase GetResponse() => new DerivedResponse();
}

Тогда мне нужно обрабатывать разные ответы по-разному. Очевидно, попытайтесь получить соответствующее поведение через 100500, если \ elses не является хорошим решением. И я решил иметь один специальный обработчик ответа для каждого конкретного ответа.

    public interface IHandlerBase<T>
        where T : ResponseBase
    {
        void Handle(T response);
    }

    public class DerivedResponseHandler : IHandlerBase<DerivedResponse>
    {
        public void Handle(DerivedResponse response)
        {

        }
    }

Кроме того, нам нужно инкапсулировать поведение, которое будет определять, какой обработчик получить для обработки конкретного ответа, и я думаю, что это неплохо. Решение для этого будет заводским. И у меня возникла проблема с этим, потому что я не знаю, что возвращать, поскольку я не знаю производного типа во время компиляции:

    public class HandlerFactory {
        public IHandlerBase<> /*WHAT RETURN HERE*/ CreateHandler(ResponseBase response)
        {
            //decide the derived type of the 'response' and return appropriate handler
        }
    }

Конечно, мы можем удалить параметр generi c, принять base класс во всех обработчиках, затем преобразовать в специальные в конкретных обработчиках, но я не думаю, что это хорошее решение. Не могли бы вы посоветовать, как это сделать чистым способом, может быть, какие-то шаблоны или решения?

1 Ответ

0 голосов
/ 30 апреля 2020

Мы можем сделать это, создав новый NotGeneri c interface:

    public interface IHandlerBase
    {
        void Handle(ResponseBase response);
    }

    public interface IHandlerBase<T> : IHandlerBase
        where T : ResponseBase
    {
        void Handle(T response);
    }

    public class DerivedResponseHandler : IHandlerBase<DerivedResponse>
    {
        public void Handle(DerivedResponse response)
        {

        }

        public void Handle(ResponseBase response)
        {
            var actualParameter = (DerivedResponse) response;
            Handle(actualParameter);
        }
    }

В этом случае у нас есть 2 метода в производном обработчике: один для фактической обработки, а другой для адаптации ( что-то вроде шаблона адаптера). Вопрос в том, что все в порядке, и, может быть, у кого-то есть лучшее решение.

...