简体   繁体   English

在协变类型的接口中使用具有协变类型的接口作为方法的返回类型

[英]Using interface with contravariant type as a return type of a method in an interface with covariant type

I need to create a factory which produces message builders and message senders. 我需要创建一个生产消息生成器和消息发送者的工厂。 I've got three interfaces: 我有三个接口:

public interface IMessageFactory<out T> where T : GenericMessage
{
    IMessageBuilder<T> CreateBuilder();
    IMessageSender<T> CreateSender();
}

public interface IMessageBuilder<out T>
{
    T Build(EmailMessage message);
    T Build(EmailTask task);
}

public interface IMessageSender<in T>
{
    void Send(T message);
}

Problem is that IMessageFactory won't compile as compiler says that 问题是IMessageFactory无法编译,因为编译器说

Invalid variance: The type parameter 'T' must be contravariantly valid on 'IMessageFactory<T>.CreateSender()'. 'T' is covariant.

If I make T covariant in IMessageSender, I cannot use it as a type of a method argument. 如果在IMessageSender中使T为协变量,则不能将其用作方法参数的类型。

And I need T to be covariant in IMessageFactory in order to do something like: 我需要T在IMessageFactory中是协变的,以便执行以下操作:

    public IMessageFactory<GenericMessage> CreateMessageFactory(DispatchService dispatchService)
    {
        if (dispatchService == DispatchService.Service1)
        {
            return new Service1MessageFactory();
        }
        else if (dispatchService == DispatchService.Service2)
        {
            return new Service2MessageFactory();
        }

        return null;
    }

where 哪里

public class Service1MessageFactory : IMessageFactory<Message<Service1Message>>
{
}

public class Service2MessageFactory : IMessageFactory<Message<Service2Message>>
{
}

public class Message<T> : GenericMessage
{
    public T SpecificMessage { get; private set; }

    public string UserLogin { get; set; }

    public Message(T message, string userLogin)
    {
        SpecificMessage = message;
    }
}

I've reached a deadlock. 我陷入僵局。 Any ideas? 有任何想法吗?

UPD. UPD。

Probably I'm doing everything wrong, so I'll just describe what I basically need, and maybe you can give me some hints about how can I achieve it. 可能我做错了所有事情,所以我只描述我基本需要的东西,也许您可​​以给我一些有关如何实现它的提示。

So, I need: 因此,我需要:

  1. to be able to create builders and senders for messages of different types 能够为不同类型的消息创建构建器和发送者
  2. to have factories that will create builders and senders for each message type 有工厂将为每种消息类型创建构建器和发送者
  3. to have factory method that will create factory according to a parameter passed to it 具有将根据传递给它的参数创建工厂的工厂方法

Any ideas? 有任何想法吗?

Make IMessageFactory<T> non-variant. 使IMessageFactory<T>不变。 Problem solved. 问题解决了。

The system you've got right now is not type safe, which is why it is not legal. 您现在拥有的系统类型不安全,这就是为什么它不合法的原因。 Do you see why it is not type safe? 您知道为什么它不安全吗? Suppose you have an implementation of IMessageFactory<Tiger> which has a method CreateSender that returns an IMessageSender<Tiger> . 假设您具有IMessageFactory<Tiger>的实现,该实现具有方法CreateSender ,该方法返回IMessageSender<Tiger> You can then call Send(new Tiger()) and all is good. 然后,您可以调用Send(new Tiger()) ,一切都很好。

If you can then convert the original IMessageFactory<Tiger> to IMessageFactory<Animal> -- because it is covariant -- then you can get an IMessageSender<Animal> out of it, and you can then call Send(new Octopus()) but the underlying implementation remember only takes tigers . 如果然后可以将原始IMessageFactory<Tiger>转换为IMessageFactory<Animal> (因为它是协变的),则可以从中获取IMessageSender<Animal> ,然后可以调用Send(new Octopus())但是基本的实现方式记住老虎

The compiler knows that this can happen and therefore prevents you from compiling your program in the first place. 编译器知道会发生这种情况,因此一开始就阻止您编译程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM