web-dev-qa-db-ja.com

ジェネリックの乱用とは何ですか?

いくつかのコードをレビューしているときに、ジェネリックを使用するようにコードを変更する機会に気づきました。 (難読化された)コードは次のようになります。

public void DoAllTheThings(Type typeOfTarget, object[] possibleTargets)
{
    var someProperty = typeOfTarget.GetProperty(possibleTargets[0]);
    ...
}

このコードは、次のようにジェネリックに置き換えることができます。

public void DoAllTheThings<T>(object[] possibleTargets[0])
{
    var someProperty = type(T).getProperty(possibleTargets[0]);
    ...
}

このアプローチの利点と欠点を調査したところ、generic abuseという用語が見つかりました。見る:

私の質問は2つの部分に分かれています。

  1. このようなジェネリックに移行するメリットはありますか? (パフォーマンス?読みやすさ?)
  2. ジェネリック乱用とは何ですか?そして、型パラメーターがあるたびにジェネリックを使用していますabuse
36
SyntaxRules

ジェネリックが適切に適用されると、単にremoveコードを並べ替えるのではなく、コードを並べ替えます。主に、ジェネリックスが削除に最適なコードは、型キャスト、リフレクション、動的型付けです。したがって、ジェネリックの乱用は、ジェネリック以外の実装と比較して、型キャスト、リフレクション、または動的型付けを大幅に削減することなく、ジェネリックコードを作成することとして大まかに定義できます。

あなたの例に関しては、ジェネリックの適切な使用がobject[]T[]または類似のものに変更し、Typeまたはtypeを完全に回避することを期待します。それは他の場所で大幅なリファクタリングを必要とするかもしれませんが、ジェネリックを使用することがこの場合適切であるならば、それはあなたが終わったときに全体的に単純になるでしょう。

87
Karl Bielefeldt

私は無意味なルールを使用します。ジェネリックは、他のすべてのプログラミング構造と同様に、問題を解決するために存在です。ジェネリックについて解決する問題がない場合、ジェネリックを使用することは乱用です。

ジェネリックの特定のケースでは、それらは主に具象型から抽象化するために存在し、さまざまな型のコード実装を1つのジェネリックテンプレート(または言語がたまたま呼び出すもの)にまとめることができます。ここで、タイプFooを使用するコードがあるとします。その型を汎用のTに置き換えることもできますが、そのコードだけがFooで機能する必要がある場合は、他のコードを使用して折りたたむことはできません。したがって、解決すべき問題は存在しないため、ジェネリックを追加すると、読みやすさが低下します。

したがって、ジェネリックを導入する必要があることがわかるまで、ジェネリックを使用せずにコードを書くことをお勧めします(2番目のインスタンス化が必要なため)。そして、それからこそ、ジェネリックスを使用するようにコードをリファクタリングするときです。それより前の使用は私の目には虐待です。


これは少し奇妙に聞こえるようですので、思い出させてください:
プログラミングには例外なくルールはありません。このルールが含まれています。

コードは奇妙に見えます。しかし、それを呼び出す場合、型をジェネリックとして指定する方が見栄えがよくなります。

https://stackoverflow.com/questions/10955579/passing-just-a-type-as-a-parameter-in-c-sharp

個人的には、呼び出しコードをきれいに見せるためのこれらのゆがみは好きではありません。たとえば、「流暢」なもの全体と拡張メソッド。

しかし、あなたはそれが人気のある支持者を持っていることを認めなければなりません。たとえばマイクロソフトでさえそれを単一で使用します

container.RegisterType<IInterface,Concrete>()
0
Ewan

私には、あなたはここで正しい道を進んでいたように見えますが、仕事を終えていませんでした。

次のステップでobject[]パラメータをFunc<T,object>[]に変更することを検討しましたか?

0
sq33G