3

ユニットテストでNBuilderを試していました。優れたライブラリ。ただし、以下のクラスとインターフェースの構造については説明できませんでした。

  • 名前FizzWare.NBuilder空間内:

    • ISingleObjectBuilder
    • SingleObjectBuilderExtensions
  • FizzWare.NBuilder.Implementation

    • IObjectBuilder`
    • ObjectBuilder
  • SingleObjectBuilderExtensionsの単なるラッパーIObjectBuilderです。

  • クライアントコードは通常、Builderを与える静的メソッドを持つという名前のクラスを使用する必要がありますISingleObjectBuilder。クライアントコードでクラスをインスタンス化する必要はありません。

今、私はのポイントを取得していませんSingleObjectBuilderExtensions。それはどんな種類の設計上の利益をもたらしますか?ISingleObjectBuilder2つのインターフェースが同じ名前空間にある場合、メソッドが直接特別に含まれるのはなぜですか。

4

2 に答える 2

8

ISingleObjectBuilderインターフェイスです。インターフェイスは実装を提供できません。ISingleObjectBuilderこれは、 のすべての実装が実装を提供する必要があることを意味します。

ただし、多くの場合、メソッドには定義済みの動作があり、インターフェイスの他のメンバー (つまり のメンバー) にアクセスする必要があるだけなISingleObjectBuilderので、各実装でこれを提供するメリットはありません。

さらに、既存のすべての実装にとって重大な変更になるため、既存のインターフェイスにさらにメンバーを追加することはお勧めできません。

拡張メソッドは、これらの問題の両方を解決します。

  1. 拡張メソッドは、のすべての実装で機能しますISingleObjectBuilder
  2. 既存の API は変更されないため、既存の実装はすべて引き続き有効です。

同じ名前空間にあると便利です。使用しているコードには、その名前空間をインポートするディレクティブISingleObjectBuilderが既に含まれている可能性があります。usingしたがって、ほとんどのコードは、 IDEで押すだけで、IDE に拡張メソッドが表示さ.れます。

具体的な例を追加すると、LINQ-to-Objects は で動作しIEnumerable<T>ます。多くIEnumerable<T>実装があります。それぞれが独自の 、 、 などのメソッドを記述しなければならない場合First(...)FirstOrDefault(...)それAny(...)Select(...)大きな負担になります。ほとんどの場合、実装はほとんど同じであるため、ボットには何のメリットもありません。さらに、これを遡及的にインターフェースに取り付けることは悲惨なことでした.

補足として、メソッドの型ごとのバージョンは常に拡張メソッドよりも優先されるため (LINQ-to-Objects の場合) を実装するIEnumerable<T>Tがあり、その型に.First()インスタンス メソッドがある場合、 それから:

YourType foo = ...
var first = foo.First();

拡張メソッドではなく、バージョンを使用します。

于 2012-08-06T07:28:17.067 に答える
2

拡張メソッドはシンタックス シュガーにすぎません。これらは、公開データを「拡張」して公開する通常の静的メソッドです。

これらの拡張メソッドがプライベート フィールドを操作する必要はないようです。また、抽象クラスの代わりにインターフェイスを持つこともできます。また、抽象クラスよりもインターフェースの方が適していることは誰もが知っています。

両方が同じ名前空間にある理由は、拡張メソッドを使用するためだけに新しい名前空間を宣言することを避けるためです。LINQ を使用しようとして、インテリセンスにメソッドがないことや、コードがコンパイルされていないことに気付いたことは何回ありましたか。そこに System.Linq 名前空間が含まれていなかった理由。

于 2012-08-06T07:24:33.897 に答える