要调用此Extension方法,我需要传入第一个参数(this)。你知道为什么吗?

时间:2011-03-12 23:08:22

标签: c# .net asp.net-mvc-3 razor

在下面的html和扩展方法中,我收到以下错误:'方法没有重载'MenuLink'需要3个参数'

我认为你不需要为'this'parm传递参数。

由于

public static class HTMLHelper
{

    public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper, string linkText,  string actionName, string controllerName)
    {
        var routeData = htmlHelper.ViewContext.RouteData;
        string currentAction = routeData.GetRequiredString("action");
        string currentController = routeData.GetRequiredString("controller");

        if (actionName == currentAction && controllerName == currentController)
        {

            return htmlHelper.ActionLink(linkText, actionName, controllerName, null, new { @class = "selected" });
        }

        return htmlHelper.ActionLink(linkText, actionName, controllerName);
    }

}

}

  <ul>         
        <li id="tab10">@HunterEdge.Web.Helper.HTMLHelper.MenuLink("Overview", "Index", "Statistics")</li>   
        <li id="tab20">@HunterEdge.Web.Helper.HTMLHelper.MenuLink("Detail View", "Detail", "Statistics")</li>   
        <li id="tab30">@HunterEdge.Web.Helper.HTMLHelper.MenuLink("Trends", "Trends", "Statistics")</li> 
   </ul> 

3 个答案:

答案 0 :(得分:2)

您实际上是在调用静态类HTMLHelper而不是HtmlHelper的实例(剃刀视图中的@Html)。

调用扩展方法时,第一个参数(This)被隐式分配给调用对象。因为你不是从一个对象的实例调用,而是从静态类调用,所以没有“this”对象,因此你必须将它传递给方法。

我希望这很清楚......

http://msdn.microsoft.com/en-us/library/bb383977.aspx

为了更清楚地说明这一点:

假设我有这种扩展方法

public static class StringExtension
{
         public static void DoSomething(this string stringExtended, string someVar)
         {
           // code
         }
}

并在我的代码中使用它:

string exampleString; // some assignment
exampleString.DoSomething("abc");
实际上这个电话看起来像这样:

string exampleString; // some assignment
StringExtension.DoSomething(exampleString,"abc");

直接调用静态方法时,必须传递“this”,因为编译器不知道要向该方法发送什么。通常,您不应直接调用Extension方法。

答案 1 :(得分:1)

this作为扩展方法的第一个参数是在C#中定义扩展方法的内容。

在这种情况下会发生的是HtmlHelper的任何实例都会将扩展方法看作是实例方法(尽管它们不是),并且第一个参数会自动传递例如,该方法是从。

调用的

但是,您也可以像常规static方法一样调用扩展方法,并手动传入第一个参数。如果您使用类的静态引用来调用方法,那么必须提供第一个参数。这似乎是你案件中发生的事情。

使用为您提供的HtmlHelper实例,您应该像使用常规扩展方法一样访问静态定义,而不是使用静态定义。

<ul>         
    <li id="tab10">@Html.MenuLink("Overview", "Index", "Statistics")</li>   
    <li id="tab20">@Html.MenuLink("Detail View", "Detail", "Statistics")</li>   
    <li id="tab30">@Html.MenuLink("Trends", "Trends", "Statistics")</li> 
</ul> 

This is a link to MSDN explaining extension methods for C#

答案 2 :(得分:1)

original example that I provided我直接在Html上调用扩展方法:

<ul>
  <li>@Html.MenuLink("Overview", "Index", "Statistics")</li>
  <li>@Html.MenuLink("Detail View", "Detail", "Statistics")</li>
  <li>@Html.MenuLink("Trends", "Trends", "Statistics")</li>
</ul> 

您也可以在尝试时直接调用该方法,但需要提供html帮助器作为第一个参数:

<ul>
  <li>@HunterEdge.Web.Helper.HTMLHelper.MenuLink(Html, "Overview", "Index", "Statistics")</li>
  <li>@HunterEdge.Web.Helper.HTMLHelper.MenuLink(Html, "Detail View", "Detail", "Statistics")</li>
  <li>@HunterEdge.Web.Helper.HTMLHelper.MenuLink(Html, "Trends", "Trends", "Statistics")</li>
</ul> 

这显然是非常丑陋的,并不是那些HTML帮助者extension methods应该起作用的方式。

如果您使用第一种语法,可能会收到错误的原因是因为您没有将扩展方法放在范围内,方法是将@using HunterEdge.Web.Helper放在视图顶部或将此命名空间添加到{ {1}}的{​​1}}部分。