繁体   English   中英

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

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

我需要创建一个生产消息生成器和消息发送者的工厂。 我有三个接口:

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);
}

问题是IMessageFactory无法编译,因为编译器说

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

如果在IMessageSender中使T为协变量,则不能将其用作方法参数的类型。

我需要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;
    }

哪里

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;
    }
}

我陷入僵局。 有任何想法吗?

UPD。

可能我做错了所有事情,所以我只描述我基本需要的东西,也许您可​​以给我一些有关如何实现它的提示。

因此,我需要:

  1. 能够为不同类型的消息创建构建器和发送者
  2. 有工厂将为每种消息类型创建构建器和发送者
  3. 具有将根据传递给它的参数创建工厂的工厂方法

有任何想法吗?

使IMessageFactory<T>不变。 问题解决了。

您现在拥有的系统类型不安全,这就是为什么它不合法的原因。 您知道为什么它不安全吗? 假设您具有IMessageFactory<Tiger>的实现,该实现具有方法CreateSender ,该方法返回IMessageSender<Tiger> 然后,您可以调用Send(new Tiger()) ,一切都很好。

如果然后可以将原始IMessageFactory<Tiger>转换为IMessageFactory<Animal> (因为它是协变的),则可以从中获取IMessageSender<Animal> ,然后可以调用Send(new Octopus())但是基本的实现方式记住老虎

编译器知道会发生这种情况,因此一开始就阻止您编译程序。

暂无
暂无

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

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