Интерфейс C# Cast Object to Generi c - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь создать CQRS в моем небольшом проекте, и мне нужно привести объект к интерфейсу, у которого есть параметр c.

edit: опечатка исправлена ​​

NewUsersIdsMessageHandler newUserHandler = new NewUsersIdsMessageHandler();
IMessageHandler<IMessage> handler = newUserHandler; // compilation error


    public class NewUsersIdsMessage : IMessage
    {
        public NewUsersTroopRequestIdsMessage()
        {
        }
    }


    public class NewUsersIdsMessageHandler : IMessageHandler<NewUsersIdsMessage >
    {
        public NewUsersIdsMessageHandler()
        {
        }
    }

    public interface IMessageHandler<in TType>
        where TType : IMessage
    {
        Task<bool> Handle(TType message);
    }

Как можно Я назначаю?

IMessageHandler<IMessage> handler = new NewUsersIdsMessageHandler();

Я знаю, что могу назначить

IMessageHandler<NewUsersIdsMessage> handler = new NewUsersIdsMessageHandler();

, но это не достаточно универсально для меня. Спасибо!

1 Ответ

0 голосов
/ 26 марта 2020

Это невозможно.

Этот интерфейс

public interface IMessageHandler<out TType> where TType : IMessage
{
    bool Handle(TType Message);
}   

не может иметь спецификацию <out TType>, поскольку TType действует как входной параметр.

При наличии спецификации <out TType> требуется, чтобы иметь возможность назначать так:

IMessageHandler<IMessage> handler = newUserHandler;

Это называется ковариация и контравариантность .

Логически: IMessageHandler<IMessage> может обрабатывать сообщения любого типа, в то время как newUserHandle может обрабатывать только определенные c сообщения, поэтому это назначение не может проверять тип go через stati c во время компиляции, так как это может привести к ошибка времени выполнения.

Если конечная цель состоит в том, чтобы найти подходящий обработчик для данного типа сообщения, вы можете использовать контейнеры Io C, например, Autofac; Вот как это вам поможет:

builder
.Register(typeof(NewUsersIdsMessageHandler))
.As(typeof(IMessageHandler<NewUsersIdsMessage>))
.InstancePerDependency();

Тогда в коде

var handler = container.Resolve<IMessageHandler<NewUserIdsMessage>>()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...