2011-10-27 9 views
1

私は.NETの開発者であり、OOPについてよく知っています。 しかし、最近私は興味深い事実に気づいた。不思議な継承の変更

System.Data.SqlClient.SqlCommandは、 System.Data.Common.DbCommandに由来します。後者はSystem.IDbCommandを実装しています。 System.IDbCommandは、IDbConnectionのインスタンスConnectionを公開します。 の場合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

'SqlCommand'のやり方は、Jasonの**と** Richardの答えの両方を使う必要があります。どちらの答えも全体の2つの部分です。 – Enigmativity

答えて

4

Explicit interface implementationは、ここでは、ゲームの名前です。試してみてください:

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

implicit vs. explicit implementationの良いガイドです。

+0

'IBar.TheFoo()'を抽象としてマークし、2番目のメソッドをpublic abstractとしてマーキングしていますが、まだコンパイラエラー – Oybek

+0

を与えています。明示的に宣言されたメソッドを実装する必要があります。私はそれを抽象的にすることはできません。 – Oybek

+0

オイベック:正しい。 – jason

1

DbCommandとSqlCommandでの接続は、どちらもパブリックメソッドです。コンパイラの警告がありますが、許可されています。あなたのコードでは、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

私はリチャードはハードで行わ少しだったと思うことを言わなければならない - 彼の答えは、ジェイソンさんと同じくらい良いです彼らは両方とも質問の半分に答えました。 両者をまとめてみれば、完全な答えが得られます。

DbCommand & SqlCommandIDbCommandでこの作業を行うにはDbCommandIDbCommandの明示的な実装(ジェイソンの答え)とSqlCommandにシャドーイングパブリックメソッド(リチャードの答え)が存在しなければなりません。

私は完全な "Foo/Bar"の例を挙げます。

これらのインタフェースを持つスタート:

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 { } 

そして最後に:

public interface IFoo 
{ 
    IBar GetBar(); 
} 

public interface IBar { } 

Foo独自のGetBar方法から、IBarBarをしませ戻すためにIFooの明示的な実装を提供する必要がありますSomeFooクラスは、SomeFooインスタンスを返すには、GetBarをシャドーする必要があります。

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

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

public class SomeBar : Bar { } 

私はリチャードが、私はあなたがコンパイルエラーを取り除く影の方法にnewキーワードを追加することである情報だけを考えます。

+0

第三者の観察のための夜間。 :) –

関連する問題