2017-09-06 79 views
-1

我有域名和內容的一些接口和類:爲什麼我需要實現一個更一般的接口,如果我已經實現了一個專門的接口?

interface IElement {} 
class FloatElement : IElement {} 

interface IDomain<T> where T: IElement {} 
class FloatDomain : IDomain<FloatElement> 
{ 
    public static readonly FloatDomain Instance = new FloatDomain(); 
} 

我寫這

IDomain<IElement> foo = FloatDomain.Instance; 

,但得到了一個錯誤:

(CS0266) "Cannot implicitly convert type [...]. An explicit conversion exists (are you missing a cast?)"

(需要注意的是,儘管暗示「存在明確的轉換「,FloatDomain.Instance as IDomain<IElement>將返回null。)

我已經發現我可以通過使FloatDomain也實現IDomain<IElement>解決此問題。 但我想知道爲什麼這種解決方法是必要的!

在我的理解,FloatElementIElement一個更爲特殊的版本,即我可以隱式轉換FloatElementIElement。因此,IDomain<FloatElement>IDomain<IElement>的更專業版本,即我也應該能夠隱式地將IDomain<FloatElement>轉換爲IDomain<IElement>

或者換句話說:在我的理解,IDomain<IElement>就像是哪裏T實現IElement所有其他IDomain<T>一個基類,因爲T=IElement是最一般的可能的情況。

你能指點我的推理錯誤嗎?

+0

瞭解協方差。 – SLaks

+0

看看'List '。考慮將「列表」投射到「列表」。然後想象一下當一個DefinitelyNotAString被添加到列表中時會發生什麼。 –

回答

2

你要做的事叫做方差。在C#中,接口默認情況下不是變體,這就是爲什麼你會收到編譯錯誤。你可以標記你的界面協變逆變明確,使其工作:

interface IDomain<in T> where T: IElement {} 

interface IDomain<out T> where T: IElement {} 

詳情請參閱Variance in Generic Types

相關問題