2017-08-01 115 views
0

我正在玩一種工廠,裝飾者和責任鏈的混雜。實質上,我建立了一個接收請求對象的工廠,對其進行分析並將其傳遞給更具體的內部工廠。我已經到達了下面的結構,但它有問題。仿製藥,工廠和返回更多派生類型

public abstract class AbstractFactoryRequest { } 

public class SpecificFactoryRequest : AbstractFactoryRequest { } 

public class MoreSpecificFactoryRequest : SpecificFactoryRequest { } 

public interface IThing { } 

public interface IThingFactory<in T> where T : AbstractFactoryRequest 
{ 
    IThing GetThing(T request); 
} 

public abstract class AbstractThingFactory<T> : IThingFactory<T> where T : AbstractFactoryRequest 
{ 
    public IThing GetThing(T request) 
    { 
     var innerFactory = GetInnerFactory(request); 

     return innerFactory.GetThing(request); 
    } 

    protected abstract IThingFactory<T> GetInnerFactory(T request); 
} 

public class SpecificThingFactory : AbstractThingFactory<SpecificFactoryRequest> 
{ 
    protected override IThingFactory<SpecificFactoryRequest> GetInnerFactory(SpecificFactoryRequest request) 
    { 
     return (IThingFactory<SpecificFactoryRequest>)new MoreSpecificThingFactory(); 
    } 
} 

public class MoreSpecificThingFactory : AbstractThingFactory<MoreSpecificFactoryRequest> 
{ 
    protected override IThingFactory<MoreSpecificFactoryRequest> GetInnerFactory(MoreSpecificFactoryRequest request) 
    { 
     // return an even more specific factory... 
    } 
} 

的問題想了MoreSpecificThingFactorySpecificThingFactory內歸還new'd時出現。如上所述,ReSharper稱這是一個可疑的演員陣容,如果沒有演員陣容,編譯器會說在MoreSpecificThingFactory和IThingFactory之間沒有隱式轉換。我曾想過,也許這會工作,因爲遺產在那裏。有沒有辦法來解決這個問題?

回答

1

由於您將參數聲明爲逆變形,這意味着您只能用作方法參數的類型,而不能用作接口方法的返回類型,因此會出現此錯誤。這裏是關於泛型類型差異的an article

現在想想你想要做什麼。如果你轉換爲不太具體的類型,那就意味着你可以將更少的特定參數傳遞給只接受更多特定參數的方法,而你顯然不能這樣做。

爲了使這個科協工作,你應該定義MoreSpecificThingFactory如下:

public class MoreSpecificThingFactory : AbstractThingFactory<SpecificFactoryRequest> 
{ 
    protected override IThingFactory<SpecificFactoryRequest> GetInnerFactory(SpecificFactoryRequestrequest) 
    { 
     if (request is MoreSpecificFactoryRequest) 
     { 
      // return an even more specific factory... 
     } 
     // throw an exception or do something else 
    } 
} 

編輯:

看來你需要把這裏chain of responsibility模式

+0

謝謝。我認爲這是我正在尋找的。我會稍後處理它,並在當時選擇答案。另外,我想提一提,我正在考慮「責任鏈」,並出於某種原因輸入了「指揮鏈」。我會解決這個問題。 – bubbleking