2013-05-29 48 views
0

我需要創建一個生成消息構建器和消息發送器的工廠。我有三個接口:在協變類型的接口中使用具有逆變類型的接口作爲方法的返回類型

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. 

如果我將T協變的IMessageSender,我不能把它作爲一個類型的方法參數。

我需要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. 有工廠工廠方法將根據傳遞給它的參數創建工廠
+0

爲什麼你需要'IMessageFactory'在'T'中是不可逆的? –

+0

@BenReich我已經更新了我的問題以清楚說明。 – HiveHicks

+0

如何爲'MessageBuilderFactory '和'MessageSenderFactory '提供接口,並且具有繼承這兩者的不變「MessageHandlerFactory 」? – supercat

回答

4

任何想法?

使IMessageFactory<T>非變形。問題解決了。

您現在擁有的系統不是類型安全的,這就是爲什麼它不合法。你明白爲什麼它不安全嗎?假設您有一個實現IMessageFactory<Tiger>,它的方法CreateSender返回IMessageSender<Tiger>。然後你可以撥打Send(new Tiger()),一切都很好。

如果能夠再轉換原IMessageFactory<Tiger>IMessageFactory<Animal> - 因爲它是協變的 - 那麼你就可以得到一個IMessageSender<Animal>出來,然後你可以調用Send(new Octopus())但底層實現記得只需要老虎

編譯器知道這可能發生,因此阻止您編譯您的程序。

+0

也許你可以告訴我一個正確的方法,考慮到我添加到我的問題的目標?我一直在努力使這項工作已經3個小時了。 – HiveHicks

+0

我可以使IMessageFactory 非變體,但問題是 - 如何實現CreateMessageFactory()方法。 – HiveHicks

相關問題