2010-09-24 5 views
0

Dans notre projet ASP.NET MVC, nous avons une méthode d'extension HtmlHelper pour générer une carte google statique.Est-ce une bonne pratique de faire une méthode d'extension qui n'utilise jamais l'objet étendu?

public static MvcHtmlString StaticMap(this HtmlHelper helper, string address, string alt, int width, int height, int zoom) 
{ 
    var src = new Uri("http://maps.google.com/maps/api/staticmap?markers=size:mid|color:red|{0}&zoom={1}&size={2}x{3}&maptype=roadmap&sensor=false".FormatInvariant(Uri.EscapeUriString(address), zoom, width, height)); 
    var href = new Uri("http://maps.google.com/maps?f=q&source=s_q&hl=en&q={0}".FormatInvariant(Uri.EscapeUriString(address))); 

    var img = new TagBuilder("img"); 
    img.MergeAttribute("src", src.ToString()); 
    img.MergeAttribute("alt", alt); 

    var link = new TagBuilder("a") { InnerHtml = img.ToString() }; 
    link.MergeAttribute("href", href.ToString()); 

    return MvcHtmlString.Create(link.ToString()); 
} 

Pour ce nouveau projet, nous essayons également de conserver la règle d'analyse de code. Maintenant, évidemment, l'analyse Visual Studio Code indique que nous devrions supprimer le paramètre helper car il n'est pas utilisé. Cela m'a fait me demander si une méthode d'extension devrait toujours utiliser l'objet étendu et si ce n'est pas le cas, alors peut-être que ce ne devrait pas être une méthode d'extension.

Est-ce que quelqu'un a un lien vers une ligne directrice ou une explication qui m'aiderait à décider?

Répondre

4

La distinction du code d'utilisation entre une méthode d'extension et une méthode statique est purement conceptuelle; l'un concerne un objet d'un type particulier de la même manière qu'une méthode d'instance, et l'autre non.

Cela étant, je poserais la question suivante: «est-il logique de considérer cette opération sur un objet HtmlHelper? Cela devient à son tour "fait en considérant les objets HtmlHelper pour fournir cette opération, a du sens?". Si j'ai répondu «oui» à cette question, je considérerais une méthode d'extension comme une approche raisonnable, que j'aie utilisé un objet HtmlHelper ou non. Inversement, si j'ai répondu «non» à cette question, je considérerais une méthode d'extension comme une approche mal avisée, même si l'objet HtmlHelper a été utilisé. L'analyse de code fait un meilleur travail d'analyse de code que les concepts, donc il donne un avertissement ici. C'est imparfait, et il y a d'autres cas où ignorer un paramètre est raisonnable (maintenir la compatibilité avec une version précédente ou une interface étant le meilleur des cas, "réservé pour un usage futur" étant un cas plus discutable). Il est à noter que dans certaines langues (enfin, C++ pour un), vous pouvez laisser un nom de paramètre avec précision pour signifier "ce paramètre est dans la signature, mais ne sera pas utilisé". J'aime bien ça, car il est vrai que généralement ne pas utiliser un paramètre est un mauvais signe, donc c'est bien d'avoir un moyen d'indiquer que vous êtes délibéré dans ce domaine.

Editer:

Une autre justification. Imaginez que vous utilisiez une méthode d'extension sur une classe qui utilisait l'objet pertinent. Maintenant, imaginez que vous réalisez que vous pouvez le rendre plus fiable, efficace ou autrement «meilleur» pour une certaine valeur de «meilleur» en réécrivant de telle façon que vous n'utilisez plus l'objet. Ne devriez-vous pas être autorisé à conserver la méthode d'extension maintenant que vous l'avez améliorée? Devriez-vous être obligé de rester avec la version inférieure?

+0

"Ne devriez-vous pas être autorisé à conserver la méthode d'extension maintenant que vous l'avez améliorée?" - Ma réponse à cette question est généralement oui, vous ne devriez pas ** ** conserver la méthode d'extension. En supprimant un paramètre, j'ai rendu le code plus simple et plus clair. Par exemple. Si je réussis à changer 'void doItFast (ce booster SpeedBooster, string IT)' void doItFast (string IT) ', je voudrais changer mes appels de' instBoost.doItFast (instIT) 'à doItFast (instIT)' . – Brian

+0

@Brian. C'est un changement de rupture si la méthode est publique. C'est potentiellement beaucoup de changements, et donc beaucoup de bugs potentiels, si ce n'est pas public. En règle générale, je passerais probablement à la version plus propre, mais pas si elle était publique et que je n'avais pas de contrôle sur tout en utilisant du code, car je ne considérerais pas cela comme un changement important. –

+0

Je suis d'accord avec tous vos points, même si ceux-ci sont plus sur les changements en général que ce changement spécifique. Cela dit, je pensais, peut-être incorrectement, que vous utilisiez ceci comme une expérience de pensée pour justifier l'utilisation d'une méthode d'extension sur une classe qui n'utilisait pas l'objet, pour appuyer votre argument selon lequel il était normal d'utiliser des méthodes d'extension. semble que l'objet fournit l'opération. Je n'étais pas d'accord avec ce point. – Brian

12

Si vous n'utilisez pas l'objet helper, vous ne développez rien et il n'y a aucune raison de ne pas en faire une méthode statique régulière dans votre propre espace de noms.

+0

Droite. En en faisant une méthode d'instance, vous vous liez à une instance de 'Foo' quand vous n'en avez pas besoin. Si vous n'avez pas déjà une instance dans votre bloc de code, vous en aurez * pour en créer un simplement pour appeler une méthode qui n'a rien à voir avec l'instance créée! Quel gâchis. (* Bien sûr, la méthode d'extension statique peut être appelée directement en utilisant 'FooExtensions.Bar (null, [reste des arguments ici ...]) ' –

+1

Eh bien non, il étend clairement quelque chose si elle est utilisée dans cette extension ou non. Le code appelant peut maintenant faire quelque chose avec un tel objet qu'il ne pouvait pas faire avant, donc c'est étendu. Le fait que les membres existants ne soient pas utilisés pour ce faire est un détail de mise en œuvre. –

1

Pourquoi avez-vous fait cette méthode d'extension pour commencer? Je dirais que ce n'est pas quelque chose que tu devrais faire. Je ne peux pas penser à une bonne raison pour cela.

+0

Surtout parce que c'est à peu près tout ce que vous voyez dans ASP.NET MVC: Méthodes d'extension pour tout –

+0

@ Pierre-Alain, alors que je suis la seule personne à prétendre qu'une telle approche est raisonnable, je ne vois pas que une bonne raison. Cela ressemble un peu trop à "bien, tout le monde l'a fait ...". –

+0

Je ne veux pas dire que mon approche est bonne, ni que j'énonce un argument, mais en apprenant, vous avez tendance à copier ce que vous voyez. Ensuite, c'est quand vous posez des questions sur ce que tout le monde fait que vous apprenez vraiment. –