1

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

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. 拥有根据传递给它的参数创建工厂的工厂方法
4

1 回答 1

4

有任何想法吗?

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

您现在拥有的系统不是类型安全的,这就是它不合法的原因。你明白为什么它不是类型安全的吗?假设您有一个实现, IMessageFactory<Tiger>它有一个CreateSender返回IMessageSender<Tiger>. 然后你可以打电话Send(new Tiger()),一切都很好。

如果您可以将原始转换IMessageFactory<Tiger>IMessageFactory<Animal>- 因为它是协变的 - 那么您可以从中得到一个IMessageSender<Animal>,然后您可以调用Send(new Octopus())但底层实现记住只需要 Tigers

编译器知道这可能会发生,因此会阻止您首先编译程序。

于 2013-05-29T16:48:02.893 回答