簡體   English   中英

我可以在C#中使用子類實現接口嗎?

[英]Can I implement an interface using a subclass in C#?

給出以下內容:

class A : B {}

interface I
{
 B TheObject {get;set;}
}

我能以某種方式這樣做嗎?

class C : I
{
 public A TheObject {get;set;} 
}

請注意,接口具有基類,實現具有子類。

試一試

class C : I
{
 public A TheObject {get;set;} 
 B I.TheObject 
 {
   get { return A; }
   set { A = value as A; }
 }
}

您可能需要根據需要修改B setter。 以這種方式實現接口具有以下結果。 處理類型為C的變量時,您將無法訪問B TheObject。 如果需要,您需要聲明一個I變量並將其分配給您的C var。 以這種方式實現我稱為顯式實現。

例如

C c = new C();
A a = c.TheObject; // TheObject is an A
I i = c;
B b = i.TheObject;

您無法執行此操作,因為接口實現的返回類型必須匹配。 但是,我為什么不能這樣做的理由是錯誤的(正如評論中所指出的那樣)。 您必須匹配簽名,但您可以從C返回一個新的A ...

public class C : I
{
  public B TheObject { get { return new A(); } set {} }
}

不,你不能。 至少沒有C#4.0的協方差/逆變量功能。

不。 編譯器會抱怨類型不匹配。

此外,我將不同意保羅:我認為差異不會對你的情況有所幫助。 看看Skeet 在這里對方差的看法。

不,假設如下:

class D : B {}

C c = new C();
c.TheObject = new D(); // error. D is not A, A is not D

使用上面的類我仍然可以使用D實現接口I對象,但我們假設我想將C實例的TheObject屬性設置為D的實例。 我不能,因為DA是兄弟姐妹。 它們都繼承自同一個類,因為它們在界面中會很好,但是聲明你期望A困擾編譯器。 A的實例不是D的實例,但A和D的實例都是B的實例。

這條規則遵循Liskov替代原則

PS我想感謝Troels Knak-Nielsen對這一微妙之處的開放態度。

您所考慮的是協方差/逆變,但即使使用C#4.0,這也行不通。 如果您只有對接口的引用,它仍然需要可用。

getter可以工作,因為A也是B,但是setter不能工作,因為實現需要A,而接口允許你將TheObject設置為B.通常,返回值可以是子類型,參數可以是具有協方差/逆變的基類型。 但僅限於C#4.0。

這編譯:

class B { }

class A : B { }

interface I<T> where T : B
{
    T TheObject { get; set; }
}

class C : I<A>
{
    public A TheObject { get; set; }
}

但我認為這不是你想要的?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM