Why is this required here (extension method)?

Meta Note: The word "this" cannot be found.

I just came across a strange script in ASP.NET where the this keyword is required. But this is not for the purpose of resolving between local and instance variables, as you saw in the constructor.

Microsoft.Web.Mvc contains a class called ControllerExtensions , and I use the RedirectToAction(Expression<Action<TController>> action) overload RedirectToAction(Expression<Action<TController>> action) . Perhaps this is special because congestion is an extension.

RedirectToAction(c => c.Index()) will not compile, and it says Cannot convert lambda expression to type 'string' because it is not a delegate type . Now it sounds to me as if I think I'm using the first overload, which takes a string.

this.RedirectToAction(c => c.Index()) compiles fine. I can also call it statically by passing this as the first parameter.

  • Why can't the compiler understand that I'm looking for an overload that accepts an expression and use this? Because the method takes an expression of the action, not just the action that should be involved. I don’t understand the Expressions namespace at all, so I don’t know the purpose of using this type of parameter.

  • Regardless of the answer to # 1, why just adding this fix it all?

+4
source share
3 answers

Extension methods work this way.

According to the C # specification ( 7.6.5.2 Extension method invocations ), extension methods are used only if the call has "one of the forms":

 expr . identifier ( ) expr . identifier ( args ) expr . identifier < typeargs > ( ) expr . identifier < typeargs > ( args ) 

This basically means that you should always have something to the left of the "." so that the compiler allows the extension method. Part of expr. must exist (and not be dynamic ) for the compiler to search for an extension method.

For example, here is a small test that demonstrates:

 namespace TestNamespace { using System; public static class TextExtension { public static void Print(this Test test) { Console.WriteLine("Found"); } } public class Test { public void Foo() { // Compiler error! Print(); // Works fine this.Print(); } static void Main() { Test test = new Test(); test.Foo(); // Fine here test.Print(); Console.ReadKey(); } } } 

Note the compiler error - since we are inside the Test instance, you cannot directly call Print() without using this. . However, we can easily execute test.Print() (or this.Print() inside the test).

+4
source

I can answer # 2: your class ( this ) has only one RedirectToAction method, so there is no ambiguity. I bet if you overloaded String , you get this error again.

0
source

There is ambiguity.

When you use 'this', you call this method -

 Controller.RedirectToAction 

Without 'this', you call the extennsion method -

 Microsoft.Web.Mvc.ControllerExtensions.RedirectToAction 
0
source

All Articles