开发者

To call this Extension method requires I pass in the first parameter(this). Do you know why?

开发者 https://www.devze.com 2023-02-16 06:18 出处:网络
On the following html and extension method I\'m getting the following error:\'No overload for method \'MenuLink\' takes 3 arguments\'

On the following html and extension method I'm getting the following error: 'No overload for method 'MenuLink' takes 3 arguments'

I didn't think you needed to pass in a parmeter for the 'this' parm.

Thanks

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, actionNam开发者_如何学Ce, 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> 


You're actually calling the static class HTMLHelper instead of an instance of a HtmlHelper (@Html in a razor view).

When calling an extension method the first parameter (the This) is implicitly assigned to the calling object. Because you're not calling from an instance of an object, but from the static class there is no "this" object, and because of that you have to pass it to the method.

I hope this is clear enough...

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

To make this more clear:

Lets say I have this extension method

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

and use it in my code like this:

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

this call in reality looks like this:

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

When calling directly to the static method you have to pass the "this" because the compiler does not know what to send to the method. Usually, you shouldn't call the Extension methods directly.


In the original example that I provided I was calling the extension method directly on 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> 

You could also call the method directly as you are trying but you need to provide the html helper as first argument:

<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> 

which obviously is extremely ugly and it is not how extension methods, which is what HTML helpers are, were supposed to work.

The reason you might be getting an error if you was using the first syntax is because you didn't bring the extension method in scope by putting @using HunterEdge.Web.Helper on the top of your view or adding this namespace to the <namespaces> section of ~/Views/web.config.


The this as the first parameter of an extension method is what defines an extension method in C#.

What happens in that case is that any instance of HtmlHelper will have the extension methods seemingly exposed on it as instance methods (although they are not) and automagically the first parameter gets passed as instance the method is being called from.

However you can also call an extension method just like a regular static method and manually pass in the first param. If you use the static reference to the class to call the method then you must supply the first parameter. This appears to be what is happening in your case.

Instead of using the static definition you should access it like a normal extension method using the HtmlHelper instances provided for you.

<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#

0

精彩评论

暂无评论...
验证码 换一张
取 消