C# 制作一个从不使用扩展对象的扩展方法是一个好的实践吗?

C# 制作一个从不使用扩展对象的扩展方法是一个好的实践吗?,c#,asp.net-mvc,extension-methods,C#,Asp.net Mvc,Extension Methods,在我们的ASP.NETMVC项目中,我们有一个HtmlHelper扩展方法来生成静态google地图 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=s

在我们的ASP.NETMVC项目中,我们有一个
HtmlHelper
扩展方法来生成静态google地图

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());
}
对于这个新项目,我们还试图保持所有的代码分析规则。现在,很明显,VisualStudio代码分析声明我们应该删除helper参数,因为它没有被使用

这让我想知道,扩展方法是否应该始终使用扩展对象,如果不使用,那么它可能不应该是扩展方法


是否有人有一个指向指南或解释的链接可以帮助我做出决定?

如果你没有使用
帮助对象,你就没有扩展任何东西,也没有理由不在你自己的名称空间中将其作为常规静态方法。

为什么你一开始就把它作为扩展方法?我认为这不是你应该做的事情。我想不出一个好的理由。

扩展方法和静态方法之间使用代码的区别纯粹是概念上的;一个与特定类型的对象相关,其方式与实例方法相同,而另一个则不同

既然如此,我会问这样一个问题,“将此操作考虑到HtmlHelper对象上有意义吗?”。这又变成了“考虑HtmlHelper对象来提供此操作有意义吗?”。如果我回答了“是”这个问题,我会考虑一个扩展方法是一个合理的方法,无论我是否使用HTMLHelpor对象。相反,如果我回答了“否”这个问题,我会考虑一个扩展方法是一个不明智的方法,即使HTMLHelpver对象确实被使用。

代码分析在分析代码使用方面比概念做得更好,因此它在这里给出了警告。这是不完美的,事实上,在其他情况下忽略参数是合理的(保持与以前版本或接口的兼容性是最好的情况,“保留供将来使用”是更具争议的情况)

值得注意的是,在一些语言中(可以,C++),可以将一个参数名精确地表示为“这个参数在签名中,但不会被使用”。我很喜欢这样,因为通常不使用参数确实是一个不好的迹象,所以很高兴有一种方法表明您在这方面是故意的

编辑:


另一个理由。假设您在使用相关对象的类上有一个扩展方法。现在想象一下,您意识到您可以通过以不再使用该对象的方式重新编写,使其更可靠、更高效,或以其他方式“更好”以获得“更好”的某些价值。既然您已经改进了扩展方法,是否应该允许您保留它?你应该被迫使用劣质版本吗?

对。通过使其成为一个实例方法,您基本上将自己绑定到了一个
Foo
实例,而您并不需要它。如果您的特定代码块中还没有实例,那么您必须*创建一个实例来调用一个与创建的实例完全无关的方法!真是浪费。(*当然,可以使用
footextensions.Bar直接调用静态扩展方法(null,[此处的其余参数…]))
不,他显然是在扩展某些东西,不管它是否在该扩展中使用。调用代码现在可以对以前无法使用的对象执行某些操作,因此对其进行了扩展。以前存在的成员在执行这些操作时没有被使用是一个实现细节。这主要是因为您在ASP.NET MVC:extension meth中看到的几乎都是这样的消耗臭氧物质everything@Pierre-阿兰,虽然到目前为止我是唯一一个认为这种方法是合理的人,但我不认为这是一个很好的理由。这听起来有点像“其他人都这么做了……”。我不想说我的方法是好的,也不想说我在陈述论点,但在学习时,你倾向于模仿你所看到的。然后,当你问别人在做什么时,你才真正学到。@Pierre Alain,是的,我只是说,在我看来,虽然有一些观点支持这种方法,但这不是其中之一。它的理由是在这样的设计问题上,我们可以成为意见分歧的一方,但仍然不同意双方所支持的观点。事实上,如果不准备这样做,那么它就不再是一个潜在的信息性讨论,而只是成为一个不透明的行,无法提供信息。“既然您已经改进了扩展方法,您是否应该不被允许保留它?”-我对这个问题的回答通常是肯定的,您不应该保留扩展方法。通过删除一个参数,我使代码更简单、更清晰。例如,如果我设法更改了
void doItFast(这个SpeedBooster,string it)
void doItFast(string IT)
,我想将调用从
instBoost.doItFast(instIT)
更改为
doItFast(instIT)“布瑞恩”。如果这个方法是公开的,那是一个突破性的改变。如果它不是公开的,它可能会发生很多变化,因此很多潜在的bug。作为一个规则,我可能也会改为更干净的版本,但是如果它是公开的,而我不可能控制所有的使用代码,因为我不认为它是一个破坏性改变的证明。我同意你的观点,虽然这些都是关于一般的变化而不是具体的变化。也就是说,我觉得,也许是错误的,你把这当作一个思想实验来证明在一个不使用对象的类上使用扩展方法是正确的,以支持你的论点,即当ey似乎是对象提供了操作。我不同意这一点。@Brian。哦,我仍然说这是扩展方法的合理使用,我用它来支持这一点——假设它第一次是一个合理的扩展方法。在