Question

J'ai une méthode d'objet qui ressemble à une usine. Vous lui donnez un type, il crée une instance et fait quelques autres choses. Une façon élégante de le faire (à mon avis) est la suivante:

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

Mais cela contrarie FxCop qui dit que c'est un mauvais style - je reçois un & "; CA1004: les méthodes génériques devraient fournir le paramètre de type &"; Attention. Quelque chose à propos de ne pas utiliser d'inférence et de trucs. Donc, la seule autre façon à laquelle je peux penser est quelque chose comme ceci:

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

Je pense que cela est inférieur à la première méthode sur de nombreux comptes, mais la règle de style ... L'article de MSDN sur l'avertissement indique même qu'il n'y a aucune raison de le supprimer.

Est-ce que je fais les choses correctement en supprimant cet avertissement après tout?

Était-ce utile?

La solution

Les avertissements FXCop ne sont que cela - des avertissements. Tout comme les avertissements implicites de la distribution, ils servent à vous faire savoir que quelque chose que vous faites peut avoir un comportement que vous ne prévoyez pas ou peut ne pas être ce que vous vouliez.

Un avertissement de distribution implicite est traité en examinant le code, en déterminant si vous avez réellement l'intention de le faire et, le cas échéant, en ajoutant une distribution explicite.

Même chose avec FXCop. Examinez l'avertissement, examinez votre code et déterminez si l'avertissement est valide. Si c'est le cas, corrigez-le. Sinon, supprimez-le. Une suppression est l’équivalent d’une distribution explicite - & "Oui, FXCop, je suis certain de vouloir le faire. &";

S'il s'agissait vraiment d'une erreur, il s'agirait probablement d'une erreur du compilateur.

Autres conseils

Je pense que vous comprenez mal ce que FxCop vous dit, probablement parce que sa formulation est loin d'être idéale. Cela signifie qu'une méthode générique doit fournir un paramètre qui est de ce type , et non pas qu'une méthode générique doit comporter une surcharge non générique fournissant un code d'exécution Tapez instance. Par exemple,

public void DoSomething<T>(T myParam);

Le myParam est le type de paramètre auquel il fait référence. Comme vous le suggérez, la raison pour laquelle il veut cela est l'inférence Cela vous permet de faire quelque chose comme ...

string foo = "bar";

DoSomething(foo);

au lieu d'avoir à écrire

DoSomething<string>(foo);

Dans votre cas, il est correct de supprimer l'avertissement, car vous souhaitez que l'utilisateur spécifie explicitement le type. Je suggérerais cependant (en supposant que vos constructeurs soient sans paramètre) de changer votre en où T: SomeBaseClass, new () . Cela signifie qu'il demandera au compilateur d'exiger que tout type de type transmis ait un constructeur sans paramètre. Cela signifie également que vous pouvez insérer new T () dans votre code.

Je n'aurais aucun problème à supprimer cet avertissement. Pour commencer, l'équivalent dans le propre code de MS est Activator.CreateInstance < T > ( )

public static T CreateInstance<T>()

Cela implique que la règle d'analyse doit déterminer si le type de retour de la méthode est couvert par le paramètre générique ...

.

Cela a déjà été mentionné à de nombreux endroits:

Et il y a eu des bugs précédents dans la règle, par exemple:

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

le déclencherait auparavant ( corrigé dans 2005 SP1 ).

Je suggère de classer un bug de connexion pour votre exemple spécifique

FxCop déclenchera cet avertissement même si vous utilisez le paramètre de type générique dans un ou plusieurs des arguments, s'il n'est pas "stripped":

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

Au moins la règle 'CA1004' a été déclenchée "par erreur". voici l'autre jour sur une méthode avec cette signature.

Pour être plus intelligent que l'équipe FxCop, je ne suis pas sûr que les règles permettent de déterminer correctement le code dans tous les cas, c'est à cela que sert le niveau de confiance:)

La deuxième approche n’est même pas équivalente à la première. Dans le second cas, vous recevez littéralement un type, mais vous ne pouvez pas instancier un objet de ce type (sauf si vous utilisez Reflection --- eeek!) Et vous devez déclarer explicitement le type de retour (ce qui annule le but des génériques commencer par).

Consultez la remarque sur sa suppression. On dirait qu'il est correct de supprimer.

EDIT: Maintenant, voici une autre idée. Que se passe-t-il si vous le changez en paramètre 'out' et ne le retournez pas via la variable de retour? Cela supprimerait-il l'avertissement alors?

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

Personnellement, je me soucierais surtout de Fxcop.

Vous semblez savoir ce que vous faites, pourquoi certains logiciels automatisés le sauraient mieux?

Eh bien, ça ne peut pas, c'est une supposition.

Tout d’abord, cet avertissement vise uniquement à garantir que les appelants font tout en connaissance de cause. Il est possible d'appeler votre méthode sans passer aucun paramètre de type car le compilateur connaît le type de l'objet à l'avance. FxCop vous dit de le laisser être implicite pour que la syntaxe d'utilisation des surcharges génériques et non génériques soit identique (je suis en désaccord avec ce principe mais c'est personnel et sans importance ici.).

Deuxièmement, votre deuxième méthode fera plus de dégâts que vous ne le pensez en ce moment. Il n'y a pas de vérification de type de compilation à ce moment-là, soyez donc averti des exceptions de distribution non valides au moment de l'exécution si vous l'utilisez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top