2

これは数え切れないほど直面している問題です..考えてみてください..

[public/private] interface IBase
{
    void DoCore();
}

public interface IDerived_A : IBase
{
    void Do_A();
}
public interface IDerived_B : IBase
{
    void Do_B();
}

ここには、いくつかの一般的な機能 (IBase インターフェイスによって提供される) を提供する 2 つの便利なインターフェイスと、それらのいずれかに固有のその他の機能があります.. c# では、IBase をパブリックとして宣言する必要があります (継承インターフェイスと同じ可視性).. 、IBase インターフェイスは誰でも見ることができます..他の人がこのインターフェイスを使用する必要はありません..ppl は IDeriver_X インターフェイスにアクセスするだけで済みます..コードのユーザーから IBase インターフェイスを非表示にするにはどうすればよいですか? 私のコードには 2 種類のユーザーがいる可能性があります。

  1. IDerived_X にアクセスする同じ名前空間/アセンブリ内のコード..
  2. IDeriver_X を含むアセンブリを参照する別のプロジェクトのコード..

ps..必要以上のインターフェイスを公開するのは嫌いです(必要とは、pplが直接使用するインターフェイスのみを意味します).ps2..私はクラスで同じジレンマに直面しています..

編集:

質問が少し誤解されているように感じます..そのために、説明を投稿します..問題はインターフェイスだけに関連しているのではありません..クラスについてもバグがあります..次のコードを検討してください..

public abstract class Vehicle
{
    // generic vehicle functionality
}
public Car : Vehicle
{
    // functionality specific to cars
}
public Truck : Vehicle
{
    // functionality specific to trucks
}

車とトラックは、私のコードのユーザーが使用できる唯一の 2 種類のオブジェクトです..仕事を簡単にし、コードの重複を避けるために、共通コードを Vehicle 抽象クラスに移動しました..しかし、それは意味しませんユーザーが車やトラックへの参照を車両変数に保存しても問題ありません..ユーザーの観点からすると、私のコードは車とトラックのみを公開する必要があります(車両やエンジン、またはコードの重複を避けるために内部で使用した基本クラスは公開しません) ..具体的には、完全な車やトラックを公開できるようにする手法を探していますが、車両やエンジンなどの他の不完全なビルディングブロックは公開できません..問題は、派生クラスがパブリックである場合、C# では基本クラスをプライベートにできないことです。 ..それはもっと理にかなっていますか?=)

4

2 に答える 2

3

上手、

  • 子インターフェースがベースから派生していることは理にかなっています
  • または子インターフェースのユーザーは、ベースのAPIにアクセスできないようにする必要があります

最初のケースでは、APIIDerived_AのコンシューマーがIBaseにアクセスできるのは合理的です。2番目にベースIBaseから派生しないでください

それ以外は、OOPを調整しています。

あなたのインターフェースの利用者として、私はIBaseとIDerived_Aの両方を提供されているので、私がIBaseにアクセスできることは合理的です。

于 2013-01-12T19:59:47.620 に答える
1

ここで何を表現しようとしているのかわかりません(したがって、完全なシナリオの説明が役立つ場合があります)。IDerived_AおよびIDerived_Bインターフェイスが である場合IBase、クライアント コードは にアクセスできる必要がありますDoCore。publicを使用すると、またはIBaseを継承する型で同じように機能する機能を一般化できます。IDerived_AIDerived_B

IDerived_Aandでのメソッド定義の繰り返しを避けたいだけでI_Derived_B、継承がIBaseIS A 関係をモデル化していない場合 (つまり、I_Derived_A と I_Derived_B は階層内で直接関連付ける必要はなく、それらの間でいくつかの機能を共有しているだけです)、おそらくすべきです。次のように、階層関係のない個別のインターフェイスを作成するだけです。

public interface ICore 
{
    void DoCore()
}

public interface INonCore_A // no more inheritance
{
    void Do_A();
}

public interface INonCore_B 
{
    void Do_B();
}

ICoreライブラリ コード内のクラスは、 と の両方を実装するように要求できるようになりINonCore_A/Bました。ICoreDoCore メソッド自体をライブラリ コードにのみ表示する場合を除き、それ自体はまだパブリックである必要があるかもしれませんが、ICore.

この 2 番目のケースで失われるのは、実装にはも実装INonCore_A する必要があることをクライアント コードに伝える方法ですICore。その機能は、たとえば scala プログラミング言語には存在しますが、C# には存在しません。存在する場合、次のように言えます。

// warning: non-existing c# syntax. Does not compile
    public interface INonCore_A {
        self: ICore => // this is scala syntax, does not work in c#
                       // it means "anyone who implements INonCore_A must 
                       // also implement ICore
            void Do_A();
    }

前述のように、これは c# では機能しないため、実装者INonCore_Aと B も実装することを確認するのは、ドキュメントとプログラマーの規律次第です。ICore

于 2013-01-12T20:21:09.303 に答える