[英]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
的實例。 我不能,因為D
和A
是兄弟姐妹。 它們都繼承自同一個類,因為它們在界面中會很好,但是聲明你期望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.