2011-10-27 40 views
1

我是一名.NET開發人員,對OOP非常瞭解。然而,最近我注意到一個有趣的事實。奇怪的繼承修改

System.Data.SqlClient.SqlCommand派生自 System.Data.Common.DbCommand。後者實現System.IDbCommandSystem.IDbCommand暴露屬性Connection其中的一個實例IDbConnection。 在DbCommand但是,此屬性返回DbConnection類型。最後在SqlCommand的屬性是SqlConnection

我試圖執行相同的操作,但它給編譯時錯誤。上面的例子是如何實現的?我如何重新創建相同的模式?

我的代碼(未編譯):

public interface IFoo { } 
public interface IBar 
{ 
    IFoo TheFoo(); 
} 

public abstract class AbsFoo : IFoo { } 
public abstract class AbsBar : IBar 
{ 
    public abstract AbsFoo TheFoo(); 
} 

public class ConcreteFoo : AbsFoo { } 
public class ConcreteBar : AbsBar { } 
+1

您需要同時使用Jason的**和** Richard的答案來執行「SqlCommand」的功能。兩個答案都是整體的兩個部分。 – Enigmativity

回答

4

Explicit interface implementation是這裏的遊戲名稱。試試這個:

public abstract class AbsBar : IBar { 
    IFoo IFoo.TheFoo() { return this.TheFoo(); } 
    public abstract AbsFoo TheFoo(); 
} 

這是關於implicit vs. explicit implementation的很好的指南。在的DbCommand和SqlCommand的

+0

我將'IBar.TheFoo()'標記爲抽象,並將第二種方法標記爲公共抽象,但它仍然給我一個編譯器錯誤 – Oybek

+0

對不起,我發現有必要實現明確聲明的方法。我不能把它抽象化。 – Oybek

+0

Oybek:正確。 – jason

1

連接都只有公共方法。會有一個編譯器警告,但它是允許的。您的代碼應該更喜歡這個像的SqlCommand/DbCommand和工作:

public interface IFoo { } 
public abstract class AbsBaseBar 
{ 
    public IFoo TheFoo() { throw new NotImplementedException(); } 
} 
public class AbsFoo : IFoo { } 
public class AbsBar : AbsBaseBar 
{ 
    public AbsFoo TheFoo() { throw new NotImplementedException(); } 
} 

public class ConcreteFoo : AbsFoo { } 
public class ConcreteBar : AbsBar { } 
+0

我認爲你在這裏理查德有點難度 - 你確實回答了**的一半**。傑森完全錯過了你的一半。我給了你一個好消息來消除負面影響。 – Enigmativity

2

我不得不說,我認爲理查德有點難以做到的 - 他的回答是一樣好傑森的因爲他們都只回答了一半的問題。 把它們放在一起,你有完整的答案。

爲了使這項工作與IDbCommandDbCommand & SqlCommand必須有在DbCommand賈森的回答)和公共方法SqlCommand陰影(理查德的回答)明確實施IDbCommand

我會給出完整的「Foo/Bar」示例。

開始與這些接口:

public interface IFoo 
{ 
    IBar GetBar(); 
} 

public interface IBar { } 

下一頁Foo必須提供明確的實施IFoo爲了回報Bar,不IBar,從自身GetBar方法:

public abstract class Foo : IFoo 
{ 
    IBar IFoo.GetBar() 
    { 
     return this.GetBar(); 
    } 

    public Bar GetBar() 
    { 
     return this.GetBarInner(); 
    } 

    protected abstract Bar GetBarInner(); 
} 

public abstract class Bar : IBar { } 

最後一個SomeFoo類必須shadow GetBar才能返回SomeFoo實例:

public class SomeFoo : Foo 
{ 
    public new SomeBar GetBar() 
    { 
     return new SomeBar(); 
    } 

    protected override Bar GetBarInner() 
    { 
     return this.GetBar(); 
    } 
} 

public class SomeBar : Bar { } 

我認爲唯一的信息是理查德是我的new關鍵字添加到陰影方法你擺脫了編譯器錯誤。

+0

Hooray第三方觀察。 :) –