17

ファクトリのようなオブジェクトのメソッドがあります。タイプを指定すると、インスタンスが作成され、他にもいくつかの処理が行われます。(私の意見では)それを行うためのエレガントな方法は次のとおりです。

public T MagicMethod<T>() where T: SomeBaseClass
{
    // Magic goes here
}

しかし、これは、これは悪いスタイルだと言う FxCop を混乱させます。「CA1004: ジェネリック メソッドは型パラメーターを提供する必要があります」という警告が表示されます。推論などを使用しないことについての何か。だから、私が考えることができる唯一の他の方法は、次のようなものです:

public SomeBaseClass MagicMethod(Type T)
{
    // Same magic goes here
}

多くの場合、これは最初の方法よりも劣っていると思いますが、スタイル ルール... 警告に関する MSDN の記事では、それを抑制する理由はないとさえ述べています。

結局、この警告を抑制して正しくやっていますか?

4

7 に答える 7

18

おそらく、その言葉遣いが理想的ではないため、FxCop が伝えていることを誤解していると思います。これが意味することは、ジェネリック メソッドがその型のパラメーターを提供する必要があるというTypeことであり、ジェネリック メソッドがランタイムインスタンスを提供する非ジェネリック オーバーロードを持つ必要があるということではありません。例えば、

public void DoSomething<T>(T myParam);

myParam参照しているパラメーターの種類です。これが必要な理由は、あなたが示唆するように、推論のためです。これにより、次のようなことができます...

string foo = "bar";

DoSomething(foo);

書く代わりに

DoSomething<string>(foo);

あなたの場合、ユーザーにタイプを明示的に指定してもらいたいので、警告を抑制しても問題ありません。ただし、(コンストラクターがパラメーターなしであると仮定して) に変更することをお勧めしwhereますwhere T : SomeBaseClass, new()。これは、渡された型がパラメーターなしのコンストラクターを持つことを要求するようにコンパイラーに指示することを意味します。これは、コードで実行できることも意味しますnew T()

于 2009-07-31T12:16:01.567 に答える
5

この警告を抑制しても問題はありません。手始めに、MS独自のコードで同等のものはActivator.CreateInstance<T>()

public static T CreateInstance<T>()

これは、メソッドの戻り値の型がジェネリック パラメーターでカバーされているかどうかを分析ルールで考慮する必要があることを意味します...

これは、以前に多くの場所で言及されています。

また、ルールには次のような以前のバグがありました。

public static void GenericMethod<T>(List<T> arg);

以前はトリガーされていました ( 2005 SP1 で修正済み)。

特定の例について接続バグを報告することをお勧めします

于 2009-07-31T12:36:30.530 に答える
2

FXCop の警告はまさに警告です。暗黙のキャスト警告と同様に、これらは、実行していることが予期しない動作をする可能性があること、または意図したものではない可能性があることを知らせるのに役立ちます。

暗黙のキャスト警告は、コードを調べて、本当にそうするつもりだったかどうかを判断し、そうである場合は明示的なキャストを追加することで対処します。

FXCopでも同じです。警告を見て、コードを見て、警告が有効かどうかを判断してください。その場合は、修正してください。そうでない場合は、それを抑制します。抑制は、明示的なキャストと同等です。「はい、FXCop、これをやりたいと確信しています。」

もしそれが本当にエラーなら、おそらくコンパイルエラーでしょう。

于 2009-08-01T04:47:14.627 に答える
1

FxCop は、1 つ以上の引数でジェネリック型パラメーターを使用した場合でも、それが "削除" されていなければ、その警告を発します。

public void LinkedList<T> Slice<T>(LinkedList<T> collection, Predicate<T> match)
{
    ...
}

少なくともルール 'CA1004' は、先日、このシグネチャを持つメソッドで「誤って」起動されました。

FxCopチームよりも賢いので、ルールがすべてのケースでコードを正しく判断できるかどうかはわかりません。それが信頼レベルです:)

于 2009-08-01T10:14:55.120 に答える
0

2 番目のアプローチは、最初のアプローチと同等ではありません。2 番目のものでは、文字どおり型が与えられますが、その型のオブジェクトをインスタンス化することはできず (リフレクションを使用しない限り --- うーん!)、戻り値の型を明示的に宣言する必要があります (ジェネリックの目的を無効にします)。から始めます)。

抑制については、このメモを参照してください。抑えても良さそうです。

編集:ここに別のアイデアがあります。それを「out」パラメーターに変更し、return 変数を介して返さなかった場合はどうなるでしょうか? その場合、警告は削除されますか?

public void MagicMethod<T>( out T retVar ) where T: SomeBaseClass
{
    // Magic goes here
}
于 2009-07-31T12:11:10.227 に答える
0

個人的には、Fxcop のほとんどの警告を気にします。

あなたは自分が何をしているのかを知っているようですが、自動化されたソフトウェアの一部がよりよく知っているのはなぜですか?

まあ、それはできません、それは推測です。

于 2009-07-31T12:12:05.873 に答える
0

まず第一に、その警告は、発信者がすべてを故意に行うことを確認するためのものです。コンパイラは事前にオブジェクトの型を認識しているため、型パラメーターを渡さずにメソッドを呼び出すことができます。FxCop は、ジェネリック オーバーロードと非ジェネリック オーバーロードを使用するための構文が同じに見えるように、暗黙的にするように指示しています (私はその原則に同意しませんが、それは個人的なものであり、ここでは関係ありません)。

第二に、あなたの 2 番目の方法は、あなたが今考えている以上のダメージを与えます。コンパイル時の型チェックは行われないため、使用する場合は実行時に無効なキャスト例外が発生することに注意してください。

于 2009-08-01T10:07:22.563 に答える