2016-06-09 39 views
2

我有,我想使用MEF出口和出口以下的類接口模式:爲什麼接口的以下導入/導出模式不合法?

public interface IDinosaur 
{ 
    string Species { get; } 
} 

public class Pterodactyl : IDinosaur 
{ 
    public string Species { get; set; } 
    public float WingSpan { get; set; } 
} 

public interface ICage<in T> 
{ 
    void Transport(T animal); 
} 

[Export(typeof(ICage<IDinosaur>))] // <-- This appears a problem 
public class PterodactylCage : ICage<Pterodactyl> 
{ 
    public void Transport(Pterodactyl dinosaur) { } 
} 

public class DinoTransportationService 
{ 
    [Import(AllowDefault = true)] 
    private ICage<IDinosaur> m_dinosaurCage = null; 
} 

現在我會說這是合法的,因爲[Export(typeof(ICage<IDinosaur>))] indeeds出口一IDinosaurICage(這恰好是一個Pterodactyl,但是這實現了恐龍界面,所以應該沒問題吧?)。但是,這給了我一個CompositionException。他說:

[Export(typeof(ICage<Pterodactyl>))] // <-- This is ok 
public class PterodactylCage : ICage<Pterodactyl> 

,進口到:

"The export 'PterodactylCage (ContractName=\"ICage(IDinosaur)\")' is not assignable to type 'ICage`1[[IDinosaur, MyProgramme, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'." 

我可以通過改變出口來解決這個

[Import(AllowDefault = true)] 
private ICage<Pterodactyl> m_dinosaurCage = null; 

除此之外,該進口現在變得過於具體,並在事實上,在我的情況下,進口是在一個從未聽說過翼龍的不同組件中,所以這是一個不好的解決方案。 爲什麼第一個例子不合法,這種模式的解決方案是什麼?

回答

2

這是無效的,因爲(作爲錯誤信息的方式表示)的PterodactylCage實例是不能分配給ICage<IDinosaur>

ICage<IDinosaur> cage = new PterodactylCage(); // this won't compile 

這是關係到通用接口協方差\逆變,你可以閱讀它是什麼在互聯網上的許多地方(這是這裏描述的廣泛話題)。

如果你有這個接口定義:

public interface ICage<out T> // note "out" keyword 

那麼這將是合法的。但是,你不能在你的Trasport方法中使用參數作爲參數,所以這不會解決你的問題。

更多關於爲什麼這是非法的直觀。假設它是合法的。然後你有ICage<IDinosaur>實例與Tranport方法,它接受IDinosaur。但是基本類型是PterodactylCage,它是ICage<Pterodactyl>。但是,您可以將IDinosaur的任何實例傳遞給Transport方法,而不僅僅是Pterodactyl(請記住 - 我們與ICage<IDinosaur>一起使用),這會導致我們發生矛盾。這就是爲什麼直覺上它不合法。

+0

謝謝,這個解釋確實是一個很好的解釋爲什麼上述不合法。有沒有其他辦法可以讓我想做的事情成爲可能? – Yellow

+0

井ICAGE 不是你的情況下的ICAGE 。如果你以某種方式在你的導出中取得成功,並且有人將Theropods傳入你的Transport方法 - 它將在運行時失敗。所以你應該重新審視你的邏輯,因爲你所要做的只是錯誤的。 – Evk

+0

但是你可以使用ICage 而不是ICage 並導出它。你可以在裏面檢查Transport方法是什麼類型的對象作爲IDinosaur傳入(因爲它可以是任何恐龍)。 – Evk