Implement the interface specifically

I have a common interface, for example:

public interface IHandler
{
    T Process<T>(IProcess process) where T : new();
}

Sometimes I would like to implement an interface specifically, for example:

public class BoolHandler : IHandler
{
    public bool Process<bool>(IProcess process)
    {
        // Do some work - set to true or false
        return true;
    }
}

Is it possible?

EDIT: Currently, I could do this:

// Injecct handler in Main and work with single handler
ViewModel model = handler.Process<ViewModel>(process);
DifferentModel model = handler.Process<DifferentModel >(process);

With the above suggestions, I would have to do this (which I am trying to avoid - this requires me to create a bunch of handlers on the fly):

IHandler<ViewModel> handler = new Handler<ViewModel>();
ViewModel viewModel = handler.Process(process);

IHandler<DifferentModel> handler = new Handler<DifferentModel>(); // Create yet another handler - arrr
DifferentModel viewModel = handler.Process(process);
+1
source share
4 answers

As far as I understand your question (from the exchange of comments), some handlers can handle any type T(or many types T), while other handlers can handle only one type. In addition, you would like to use these processors within a single consumer polymorphically.

Here is what you can do:

:

public interface IHandler //Can handle many types
{
    T Process<T>(int process);

    bool CanProcess<T>();
}

public interface IHandler<T> //Can handle a single type
{
    T Process(int process);
}

IHandler<T> IHandler :

public class Adaptor<T> : IHandler
{
    private readonly IHandler<T> handler;

    public Adaptor(IHandler<T> handler)
    {
        this.handler = handler;
    }

    public T1 Process<T1>(int process)
    {
        if(!CanProcess<T1>())
            throw new Exception(
                "Contract violated. I cannot handle type " + typeof(T1).Name);

        return (T1)(object)handler.Process(process);
    }

    public bool CanProcess<T1>()
    {
        return typeof (T1) == typeof (T);
    }
}    

- :

public class CompositeHandler : IHandler
{
    private readonly IHandler[] handlers;

    public CompositeHandler(params IHandler[] handlers)
    {
        this.handlers = handlers;
    }

    public T Process<T>(int process)
    {
        var handler = handlers.FirstOrDefault(h => h.CanProcess<T>());

        if(handler == null)
            throw new Exception(
                "Contract violated. I cannot handle type " + typeof(T).Name);

        return handler.Process<T>(process);
    }

    public bool CanProcess<T>()
    {
        return handlers.Any(h => h.CanProcess<T>());
    }
}

IHandler<T> IHandler IHandler. , .

:

var service = new CompositeHandler(
    new TypeThatImplementsTheNonGenericInterface(),
    new Type2ThatImplementsTheNonGenericInterface(),
    new Adaptor<SomeType>(
        new TypeThatImplementsTheGenericInterface<SomeType>()));
+2

, . , , [ ]. , , , , , .

+3

   public interface IHandler<T> where T : new()
    {
        T Process(IProcess process);
    }

    public interface IProcess
    {
    }

    public class BoolHandler : IHandler<bool>
    {
        public bool Process(IProcess process)
        {
            throw new NotImplementedException();
        }
    }
0

I know that some will say that this is not a good practice, but it is an alternative. You can replace the general Ton objectin the interface and make several drives:

public interface IHandler
{
    object Process(IProcess process);
}

public class BoolHandler : IHandler
{
    object Process(IProcess process){ return true;}
}

It will be something like an implementation of an interface with a declared generic declaration, but in this way you promise users that BoolHandlerit will always return bool.

0
source

Source: https://habr.com/ru/post/1667033/


All Articles