Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the 'this' keyword required to call an extension method from within the extended class

I have created an extension method for an ASP.NET MVC ViewPage, e.g:

public static class ViewExtensions {     public static string Method<T>(this ViewPage<T> page) where T : class     {         return "something";     } } 

When calling this method from a View (deriving from ViewPage), I get the error "CS0103: The name 'Method' does not exist in the current context" unless I use the this keyword to call it:

<%: Method() %> <!-- gives error CS0103 --> <%: this.Method() %> <!-- works --> 

Why is the this keyword required? Or does it work without it, but I'm missing something?

(I think there must be a duplicate of this question, but I was not able find one)

Update:

As Ben Robinson says, the syntax to call extension methods is just compiler sugar. Then why can't the compiler automatically check the for extension methods of the current type's base types without requiring the this keyword?

like image 689
M4N Avatar asked Aug 18 '10 10:08

M4N


People also ask

Why we use this keyword in extension method?

Here, this keyword is used for binding, Geek is the class name in which you want to bind, and g is the parameter name. Extension methods are always defined as a static method, but when they are bound with any class or structure they will convert into non-static methods.

What keyword is used to define an extension method?

Extension Method uses the "this" keyword as the first parameter. The first parameter always specifies the type that the method operates on. The extension method is written inside a static class and the method is also defined as static.

Can we define extension method for a class?

An extension method must be defined in a top-level static class. An extension method with the same name and signature as an instance method will not be called. Extension methods cannot be used to override existing methods. The concept of extension methods cannot be applied to fields, properties or events.

Can you add extension methods to an existing static class?

There's no way to add them currently because the feature doesn't exist in C#.


2 Answers

A couple points:

First off, the proposed feature (implicit "this." on an extension method call) is unnecessary. Extension methods were necessary for LINQ query comprehensions to work the way we wanted; the receiver is always stated in the query so it is not necessary to support implicit this to make LINQ work.

Second, the feature works against the more general design of extension methods: namely, that extension methods allow you to extend a type that you cannot extend yourself, either because it is an interface and you don't know the implementation, or because you do know the implementation but do not have the source code.

If you are in the scenario where you are using an extension method for a type within that type then you do have access to the source code. Why are you using an extension method in the first place then? You can write an instance method yourself if you have access to the source code of the extended type, and then you don't have to use an extension method at all! Your implementation can then take advantage of having access to the private state of the object, which extension methods cannot.

Making it easier to use extension methods from within a type that you have access to is encouraging the use of extension methods over instance methods. Extension methods are great, but it is usually better to use an instance method if you have one.

Given those two points, the burden no longer falls on the language designer to explain why the feature does not exist. It now falls on you to explain why it should. Features have enormous costs associated with them. This feature is not necessary and works against the stated design goals of extension methods; why should we take on the cost of implementing it? Explain what compelling, important scenario is enabled by this feature and we'll consider implementing it in the future. I don't see any compelling, important scenario that justifies it, but perhaps there is one that I've missed.

like image 89
Eric Lippert Avatar answered Oct 11 '22 21:10

Eric Lippert


Without it the compiler just sees it as a static method in a static class which takes page as it's first parameter. i.e.

// without 'this' string s = ViewExtensions.Method(page); 

vs.

// with 'this' string s = page.Method(); 
like image 26
Ferruccio Avatar answered Oct 11 '22 23:10

Ferruccio