What is the difference between Extension Methods and Methods in C#?
I think what you are really looking for is the difference between Static and Instance Methods
At the end of the day Extension methods are some nice compiler magic and syntactic sugar that allow you to invoke a Static method as though it were a method defined on that particular class instance. However, it is NOT an instance method, as the instance of that particular class must be passed into the function.
ExtensionMethods : Let you define set of methods to a class without subclassing another benefit over inheritance.
Methods : They are used for implementation of operation defind for the the class.
See example of Extension Methods
One really nice feature of extension methods is that they can be called on null objects, see this:
myclass x = null;
x.extension_method(); // this will work
x.method(); // this won't
It is a pity, that for example most methods of string are not extension methods, after all
x.ToLower();
should return null if x is null. I mean, it would be useful.
When I need such null-transparency I prefer writing extension methods.
Related
As part of my application I have a function that receives a MethodInfo and need to do specific operations on it depending if that method is "Extension Method".
I've checked the MethodInfo class and I could not find any IsExtension property or flag that shows that the method is extension.
Does anyone knows how can I find that from the method's MethodInfo?
You can call the IsDefined method on the MethodInfo instance to find this out by checking to see if the ExtensionAttribute is applied to the method:
bool isExtension=someMethod.IsDefined(typeof(ExtensionAttribute),true);
Based on
F# extension methods in C#
it seems there is an attribute on the compiled form. So see if the method has this attribute:
http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.extensionattribute.aspx
This looks very similar to an earlier question, might be worth a look. The suggestion there was to look for classes and methods with the ExtensionAttribute which sounds like what you are after.
If you know you are getting a MethodInfo from an instance, you can easily check if the method is static. Extension methods are just syntactic sugar and get transformed into static method calls passing in the instance.
Doesn't the compiler switch all extension methods into static method calls at compile time?
myList.First();
becomes
Enumerable.First(myList);
If this is the case, then there are no extension methods in the .net runtime (where you are reflecting).
This question already has answers here:
Why are extension methods only allowed in non-nested, non-generic static class?
(3 answers)
Closed 9 years ago.
I understand that C# extension methods must be static. What I don't understand is why these extensions can't be defined in non static classes or generic ones?
Update: I am interested in the reason behind this design decision.
This is more of an observation than an answer, but...
When you call an instance method, a reference to the object you are calling is pushed onto the stack as the first argument in your method call. That first argument is "this" and is done implicitly.
When you define an extension method, you explicitly define a "this" as the first argument.
Is it possible that method resolution would be confusing if you could define extension methods and instance methods in the same class i.e. defining methods with the same name and, in effect, the same parameters when the "this" parameter is included.
Take a look to this piece of the .NET C# specification:
When the first parameter of a method includes the this modifier, that
method is said to be an extension method. Extension methods can only
be declared in non-generic, non-nested static classes. The first
parameter of an extension method can have no modifiers other than
this, and the parameter type cannot be a pointer type.
And this fragment from Jon Skeet's answer:
It's not clear to me why all of these restrictions are necessary -
other than potentially for compiler (and language spec) simplicity. I
can see why it makes sense to restrict it to non-generic types, but I
can't immediately see why they have to be non-nested and static. I
suspect it makes the lookup rules considerably simpler if you don't
have to worry about types contained within the current type etc, but I
dare say it would be possible.
Because the spec says so... Now there are probably good reasons why they wrote the spec this way.
The reason why they can't be declared in generic classes is quite obvious: given the way extension methods are called, where would you specify the type argument for the class?
The reason why it must be a static class is less obvious, but I think it makes sense. The main use case for static classes is to group helper methods together (e.g. Path, Directory, ProtectedData...), and extension methods are basically helper methods. It wouldn't make sense to be able to create an instance of Enumerable or Queryable, for example.
This question already has answers here:
Why are extension methods only allowed in non-nested, non-generic static class?
(3 answers)
Closed 9 years ago.
I understand that C# extension methods must be static. What I don't understand is why these extensions can't be defined in non static classes or generic ones?
Update: I am interested in the reason behind this design decision.
This is more of an observation than an answer, but...
When you call an instance method, a reference to the object you are calling is pushed onto the stack as the first argument in your method call. That first argument is "this" and is done implicitly.
When you define an extension method, you explicitly define a "this" as the first argument.
Is it possible that method resolution would be confusing if you could define extension methods and instance methods in the same class i.e. defining methods with the same name and, in effect, the same parameters when the "this" parameter is included.
Take a look to this piece of the .NET C# specification:
When the first parameter of a method includes the this modifier, that
method is said to be an extension method. Extension methods can only
be declared in non-generic, non-nested static classes. The first
parameter of an extension method can have no modifiers other than
this, and the parameter type cannot be a pointer type.
And this fragment from Jon Skeet's answer:
It's not clear to me why all of these restrictions are necessary -
other than potentially for compiler (and language spec) simplicity. I
can see why it makes sense to restrict it to non-generic types, but I
can't immediately see why they have to be non-nested and static. I
suspect it makes the lookup rules considerably simpler if you don't
have to worry about types contained within the current type etc, but I
dare say it would be possible.
Because the spec says so... Now there are probably good reasons why they wrote the spec this way.
The reason why they can't be declared in generic classes is quite obvious: given the way extension methods are called, where would you specify the type argument for the class?
The reason why it must be a static class is less obvious, but I think it makes sense. The main use case for static classes is to group helper methods together (e.g. Path, Directory, ProtectedData...), and extension methods are basically helper methods. It wouldn't make sense to be able to create an instance of Enumerable or Queryable, for example.
I was just curious to know how Extension methods are hooked up to the Original class. I know in IL code it gives a call to Static Method, but how it does that and why dosen't it break encapsulation.
They don't "hook up".
The Visaul Studio IDE just makes it look like it does by showing them in the intellisense lists.
The compiler "knows" how to deal with the references in order to make the right method calls with the correct parameters.
This is simply syntactic sugar - the methods are simply static methods on a separate static class. Using the this modifier lets the compiler "know" to add the ExtensionAttribute to the class to mark it as an extension method.
Since extension methods do not in fact change the class and can only access public members on it, encapsulation is retained.
From MSDN:
Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.
(emphasis mine)
Extension methods are specified by putting the this keyword in front of the first parameter of a static method:
public static void SomeExtension(this string s)
{
...
}
That is just syntactic sugar for decorating the method with System.Runtime.CompilerServices.ExtensionAttribute:
[Extension]
public static void SomeExtension(string s)
{
...
}
When the compiler sees that attribute, it knows to translate the extension method call to the appropriate static method call, passing the instance as the first parameter.
Since the calls are just normal static method calls, there is no chance to break encapsulation; the methods, like all static methods, only have access to the public interfaces of the extended types.
Extension methods are just syntactic sugar, they are just static methods. You are only able to access public fields or properties in them, just like normal static methods.
The key ingredient is that an instance method of a class isn't fundamentally different from a static method. With one small detail, they have a hidden argument. For example, the String.IndexOf(char) method actually looks like this to the CLR:
public static int IndexOf(string thisRef, char value) {
// etc...
}
The thisRef argument is what supplies the string reference whenever you use this in your code or access a member of the class. As you can see, it is a very small step from an extension method to an instance method. No changes were necessary in the CLR to support the feature.
One other minor difference is that the compiler emits code that checks if this is null for an instance method but does not do so for an extension method. You can call an extension method on a null object. While that might look like a feature, it is actually a restriction induced by the extension method not actually being a member of the class.
Internally, the CLR keeps a list of methods for the class, the MethodTable. Extension methods are not in them, preventing the compiler from emitting the callvirt IL instruction, the 'trick' that it uses to get the cheap null check. Explicitly emitting code to make the null check would have been possible but they elected not to do so. Not quite sure why.
Another automatic consequence of this is that an extension method cannot be virtual.
I think you should have a look at http://go.microsoft.com/fwlink/?LinkId=112388
I just looked at this posting: What is the best or most interesting use of Extension Methods you’ve seen?
I've never heard of extension methods. Do they apply to every language?
What is the point of them? In that particular posting I did not understand the example.
No, they do not apply to every language. They are a language-specific feature, offered by C# and Visual Basic (other languages may have adopted them since, I don't know).
The point of them is to provide a convenient syntax for calling utility methods on a class or interface. In C# 2, a utility method would be called through a static class, passing the argument in the normal way:
IEnumerable<string> someStrings;
int count = EnumerableHelpers.Count(someStrings);
With extension methods, this can be written more conveniently using something that looks like normal member method syntax:
int count = someStrings.Count();
even though Count() is not a member of the IEnumerable<string> interface. So extension methods let you appear to add members to classes or interfaces that you don't control.
They are available to C# and VB. They allow you to simulate the addition of methods to classes that are not under your control.
You could, for instance, you could add a WordCount method to string.
So instead of
MyStringUtils.WordCount( "some string" )
You could just write "some string".WordCount().
public static class MyExtensions
{
public static int WordCount(this String str)
{
return MyStringUtils.WordCount( str );
}
}
This is strictly "syntactic sugar" and aids in readability. You're essentially creating a static method that will be shown in the IntelliSense for the target type.
do they apply to every language?
No, but some languages have the same feature, though not necessarily under the same name. Those I know about are Objective-C and Groovy, where the feature is called "Categories".