3

タイプパラメータを受け取るいくつかのメソッドを含むAPIがあります。私は現在、APIの改善(よりタイプセーフ)の一環として、それらをジェネリックメソッドに変換していますが、下位互換性のために非ジェネリックバージョンを維持しています。

現在-廃止予定:

public object MyMethod(object value, Type expectedType)

新しい:

public T MyMethod<T>(object value)

ただし、Mymethodは、タイプパラメータも受け取るプライベートヘルパーメソッドを呼び出します。

private object HelperMethod(object value, Type expectedType)

質問:このプライベートヘルパーメソッドもジェネリックにする必要がありますか?

以下に私自身の答えがありますが、何かが足りないかどうか知りたいです。私はあなたの洞察にとても感謝しています。

私の答えはノーです。このプライベートメソッドをジェネリックにするべきではありません。

理由1:このヘルパーメソッドはプライベートであるため、ジェネリックにしたとしても、APIは改善されません。

理由2:ジェネリックにすると、非ジェネリックパブリックメソッドはリフレクションを使用してtypeパラメーターをこのジェネリックメソッドに渡す必要があります。これは、オーバーヘッドが増えることを意味します。

4

2 に答える 2

4

プライベートヘルパーメソッドをジェネリックにすることで、実装全体でジェネリック型の特異性を実現することでAPIを改善できます。タイプレスのSystem.Objectsをジャグリングするコアにタイプを絞り込んだ場合、実装はジェネリックスのタイプ安全性の利点を完全には実現していません。

たとえば、MyMethodのパラメータがまだSystem.Objectであるのはなぜですか?そのパラメーターがソースに由来する場合、それもタイプパラメーターである可能性が高くなります。パラメータがデータに由来する場合は、System.Objectを使用した方がよいでしょう。ジェネリックスは、ソースコードで使用する場合に最も役立ちます。これは、ソースコード式がほとんどのコンテキストで型を暗黙的に提供するためです。

ジェネリックスの隠れたコストは、APIで使用されるタイプの組み合わせによって異なります。ほとんどの型が値型(組み込み型と構造体)である場合、APIをジェネリックに切り替えると、ジェネリックコードを値型ごとに異なる方法でjitする必要があるため、メモリ消費量が増える可能性があります。汎用APIで使用される型の大部分が参照型(クラスとインターフェース)である場合、すべての参照型が同じJITコードを共有するため、コード/メモリの急増は問題になりません。

古いAPIで新しい汎用APIを呼び出すコストが、a)測定可能で、b)許容できるかどうかは、プライベートヘルパーメソッドで何をしているか、特にプライベートヘルパーメソッドがTypeパラメーターで何をしているかに完全に依存します。

ヘルパーメソッドの実装がかなり軽量で、古いAPIを適応させて新しい汎用ヘルパーを呼び出すコストが許容できないと判断した場合は、ヘルパーメソッドの実装を古いものと並べて複製することを検討します。スタイルと新しいジェネリックスタイルの1つ。これにより、APIスタイル間のクロスオーバー変換コストが排除され、内部コードのメンテナンス作業がわずかに増加する代わりに、古いAPIに新しいバグが導入されるリスクが排除されます。

于 2012-07-06T21:37:56.620 に答える
1

非ジェネリックメソッドをサポートする予定の時間、呼び出される頻度、反射への影響などに依存すると思います。

必要な型安全性を活用するために、できるだけ汎用的な機能が必要になると思います。次に、非ジェネリックバージョンを後付けして、必要に応じてジェネリックバージョンを使用し、最終的にはできるだけ早く非推奨にします。

于 2012-07-06T21:06:24.010 に答える