2012-05-29 39 views
24

如果一個接口指定一個返回另一個接口的屬性或方法,爲什麼不允許第一個接口的實現將返回類型「更改」爲更具體的類型?爲什麼接口實現不能返回更具體的類型?

讓我們舉個例子來說明:

interface IFoo 
{ 
    IBar GetBar(); 
} 
interface IBar 
{ } 

class Foo : IFoo 
{ 
    // This is illegal, we are not implementing IFoo properly 
    public Bar GetBar() 
    { 
     return new Bar(); 
    } 
} 

class Bar : IBar 
{ } 

我知道如何使它發揮作用,這是我的關心。

我就可以既:中GetFoo()IBar

  • 更改返回類型,或
  • 明確實現該接口並調用GetBarIFoo.GetBar()方法

什麼我真的問是不僅允許上面的代碼編譯的推理。是否有任何情況下,上述不符合IFoo指定的合同。

+1

還有第三種方式,比上述兩種稍微方便一些。您可以使用抽象類實現接口。然後,在你的「具體」類中繼承抽象類而不是接口。然後在你的「具體」類中,你可以用「new」關鍵字隱藏基本方法。它對我來說工作得體。 – BrainSlugs83

+0

我覺得BrainSlugs83的評論是一個答案,因爲它提供了一個體面的解決方法。 –

回答

17

通常情況下,我會說這將是一種平衡好處與支持這種功能的額外複雜性的情況。 (所有功能都需要努力設計,記錄,實現,測試,然後開發人員也需要接受相關教育。)請注意,如果您想要支持返回實現了接口的值類型,可能會有一些非常複雜的情況(因爲這會以不同的表示方式結束,而不僅僅是參考)。

在這種情況下,我不認爲相信 CLR甚至支持這樣的功能,這將使C#非常難以乾淨利落。

我同意這將是一個有用的功能,但我懷疑它沒有被視爲有用,足以保證所需的額外工作。

+7

喬恩我有問題嗎?你如何在1分鐘內寫出這麼多? –

+0

+1因爲「......增加了......的複雜性」這一點,但我不確定它可能有用。畢竟一個接口是一個契約,如果你需要一個像這樣的方法,你可以明確地實現接口方法,並且用_required_返回類型添加另一個方法,那麼......那是什麼? –

+1

@Adriano:你可以,是的。但令人討厭的是,你必須這樣做,顯式接口實現有其自身的缺點和複雜性。我可以避免顯式的接口實現,如果支持協變返回類型,這將是另一個地方,我可以避免它:) –

3

您所要求的功能稱爲「返回類型協方差」。正如on Wikipedia所指出的那樣,Java和C++都擁有它,這可能讓C#沒有。

Eric Lippert在對此答案的評論中證實,此功能未實施,因爲它不被認爲值得實施。 (這個答案的前一個修訂版將該決定分配給Eric個人;他說這是不正確的,並且如果任何一個人對此負責,則是Anders Hejlsberg。)

無論如何,現在有各種提議添加它的語言(見https://github.com/dotnet/roslyn/issues/357,https://github.com/dotnet/csharplang/blob/master/proposals/covariant-returns.md,https://github.com/kingces95/coreclr/issues/2),所以也許它會在未來幾年得到實施。根據這些討論,似乎沒有什麼深層次的原因可以解釋爲什麼該特性不應該存在於C#原則上 - 相反,它從來沒有被認爲值得任何人付諸實施。

+3

在我加入C#設計團隊之前的幾年中,該功能已添加到Java中,因此我的意見在當時未被考慮。雖然我是在C#設計團隊,根據我的記憶,此事從未正在審議的設計團隊。因此,更準確地說,*安德斯*不認爲這是值得的。我不認爲這是一個壞的功能,如果C#擁有它,我會使用它。我同意有更多的功能,但我會提出更高的優先級。 –

相關問題