30

拡張メソッドは、任意のクラスに必要な関数を多数追加できる非常に便利な機能です。しかし、私に問題を引き起こす可能性のある不利な点があるかどうかは疑問です. コメントや提案はありますか?

4

7 に答える 7

38
  • 拡張メソッドをインポートする方法 (つまり、名前空間全体を一度にインポートする方法) は細かくありません。残りのすべてを取得せずに、名前空間から 1 つの拡張機能をインポートすることはできません。
  • メソッドがどこで定義されているかは、ソース コードからすぐにはわかりません。これは利点でもあります。つまり、何らかの理由で同じ場所に配置できない場合でも、コードを型の残りのメソッドと一貫性を持たせることができるということです。言い換えれば、コードは高レベルで理解するのがより簡単ですが、実行されているものという点ではより複雑です。これはLINQ全般にも当てはまると思います。
  • プロパティ、インデクサー、演算子、コンストラクターなどではなく、拡張メソッドのみを使用できます。
  • サード パーティのクラスを拡張していて、新しいバージョンで同じシグネチャを持つ新しいメソッドが導入された場合、呼び出し元のコードの意味が変わったことを簡単に知ることはできません。新しいメソッドが拡張機能に非常にているが、微妙に異なる境界条件 (またはその他のもの) を使用している場合、これは非常にトリッキーなバグにつながる可能性があります。ただし、発生する可能性は比較的低いです。
于 2008-11-23T07:39:38.457 に答える
5

いくつかのこと:

  • VS.NET の内部にいる場合を除き、拡張メソッドがどこから来たのかが常に明確であるとは限りません。
  • リフレクションまたは C# 4.0 の動的ルックアップを介して拡張メソッドを解決できない
于 2008-11-23T06:36:56.853 に答える
3

拡張メソッドは楽しいものですが、潜在的な問題があります。たとえば、拡張メソッドを作成し、別のライブラリが同じシグネチャを持つ拡張メソッドを作成した場合はどうなるでしょうか? 両方の名前空間を使用するのは困難です。

また、発見されにくいとも言えます。これ次第だと思います。コードをクラスにラップする必要がある場合もあれば、その機能を拡張メソッドとして追加しても問題ない場合もあります。

私は通常、拡張メソッドを独自のクラスまたは BCL クラスのラッパーとして作成し、それらを別の名前空間に配置します。例: Utils および Utils.Extensions。そうすれば、拡張機能を使用する必要はありません。

于 2008-11-23T06:16:31.697 に答える
3
  • 静的メソッドでの null チェックは異なります。必ずしも良くも悪くもありませんが、違います。開発者はそれを理解する必要があります。null 値でメソッドを呼び出せることは予期せぬことであり、(場合によっては) 非常に便利です。

  • ポリモーフィズムなし (ただし、オーバーロードはサポートされています)

  • 2 つの拡張メソッドがソース タイプに対して競合する場合 (そしてどちらも "より良い" と見なされない場合) は、あいまいさで混乱する可能性があります。コンパイラはどちらの使用も拒否します...つまり、アセンブリAに拡張メソッドを追加すると、アセンブリBの無関係なコードが壊れる可能性があります*。これを数回見ました...

  • C# 2.0 では in を使用できないため、C# 2.0 用のライブラリを作成している場合は役に立ちません。

  • [ExtensionAttribute] が必要です。つまり、.NET 2.0 用のライブラリを作成している場合は、問題が発生します。独自の [ExtensionAttribute] を宣言すると、.NET 3.5 呼び出し元と競合する可能性があります。

誤解しないでください-私は大ファンです!

おそらく、私が現在、C# 2.0 および .NET 2.0 の呼び出し元で動作する必要があるライブラリを作成していると推測できます。また、(厄介なことに) 拡張メソッドが本当に非常に便利な場所です!

*=コンパイラのみ。すでにコンパイルされているコードは問題ありません

于 2008-11-23T11:53:18.977 に答える
0

既存のコードについて詳しく知らずにメソッドを追加することは想像しがたいです。たとえば、サードパーティのクラスを使用して何かをしている場合、元の開発者ではなく、オブジェクトがどのように構造化されているかがわからない場合、このクラスの機能を拡張する必要はありません。クラス?見えないときに運転するのが無意味であるのと同じように、そのようなことをするのはほとんど無意味です。マイクロソフトのデザイナー/コードによって実装されている LINQ の場合、シーケンスの実装の内部についての知識があり、すべてをカウントする Count メソッドを追加して機能を拡張したいので、非常に理にかなっています。シーケンス内の要素。こう言ったことで、

于 2015-05-18T12:20:05.560 に答える
0

不利な点に関して言えば、それらはマクロに少し似ていると思います。追加した拡張機能に他の人が慣れていない可能性があるため、保守が困難なコードになる可能性があります。

于 2008-11-23T06:08:34.723 に答える