Reputation: 2923
I've been refactoring some old code lately and a lot of methods are useful as extension methods to foundational types such as double
, float
, int
, string
, etc. However, as I pitter-patted along making great progress, a thought occurred to me. There are multiple ways to access an extension method. Let's create a container class called Extensions
and add a basic extension method (at first), and a dummy class we shall call Dummy
with a simple method that utilizes our extension method called DoIt
.
public static class Extensions {
public static double ToRadians(this double degrees) => degrees * Math.PI / 180.0;
}
public class Dummy {
public void DoIt() {
double radians = Extensions.ToRadians(45.0);
double degrees = 90.0;
radians = degrees.ToRadians();
}
}
Not the most elegant example, but it demonstrates the widely known access to extension methods. Now lets create an idiotic and pointless extension called WasteOfTime
for our Dummy
class, but within the Extensions
class.
I'm not to sure why you would do this, but for the sake of the question, let's do it!
public static class Extensions {
...
public static void WasteOfTime(this Dummy dummy) { }
...
}
Alright, now we have this perfect little method that should have just been placed in the Dummy
class. Well, since extension methods work off of instances of types, you should be able to call WasteOfTime
from the Dummy
class' special method called DoIt
.
public void DoIt() {
...
WasteOfTime();
...
}
Oh, but wait, you can't do that! The method couldn't be found! Let's qualify it with the this
keyword!
this.WasteOfTime();
That's better, it compiles! It works! It is a waste of time! Cool!
I would NOT consider actually doing this, but out of curiosity I gave it a try. If you can give a valid example as to why this would ever be a good idea, feel free to share, but I believe it is one of those; what were you thinking types of implementations.
Why did I have to qualify the extension method since modern compilers remove the need for qualifying fields, properties, and methods with the this
keyword?
The only thing I can think of is that the extension method is technically static to the base class.
Upvotes: 1
Views: 214
Reputation: 1499830
Firstly, I'll note that there are perfectly good reasons to call extension methods on this
. For example, you might be writing a collection class and want to use LINQ within it. Nothing wrong with that. Now, in terms of the question:
Why did I have to qualify the extension method since modern compilers remove the need for qualifying fields, properties, and methods with the this keyword?
It's not a matter of the modernity of the compiler - it's about what the language specification says. From ECMA-334, section 12.7.6.3:
In a method invocation (§12.6.6.2) of one of the forms
expr . identifier ( ) expr . identifier ( args ) expr . identifier < typeargs > ( ) expr . identifier < typeargs > ( args )
if the normal processing of the invocation finds no applicable methods, an attempt is made to process the construct as an extension method invocation. If expr or any of the args has compile-time type
dynamic
, extension methods will not apply.
A method call of the form Method()
is not in one of those forms, as there's no expr
.
So the compiler's just obeying the rules of the specification. As for why it's designed that way, that's slightly different. I don't know the details of this (although I can see if they're in one of the annotated versions of the spec) but I suspect that the fact that Foo()
can either refer to an instance method or a static method in the current class or any of the base classes makes the whole thing a little trickier. (As of C# 6 it could also be a static method in any of the methods imported by a using static
directive, mind you...)
Upvotes: 3