Extension Methods in C# [modified]
-
I was reading this on the MSDN site: A new feature made available in Visual Basic 2008, however, lets you extend any existing type's functionality, even when a type is not inheritable. And these extension methods play a crucial role in the implementation of LINQ. Many types that already exist can't be easily updated without breaking existing code. An example of this is the interface IEnumerable(Of T). In order to support LINQ, new methods had to be added to this interface, but changing the interface by adding new methods would break compatibility with existing consumers. Adding a new interface was a possibility, but creating a new interface to supplement the existing IEnumerable(Of T) interface would have appeared to be an odd design. What was needed was a way to extend existing types with new functionality without changing the existing contract. Is this true? That extension methods were added for the purpose of supporting Linq? The article[^] also makes some wierd points: Extension methods allow you to add functionality to a type that you don't want to modify, thus avoiding the risk of breaking code in existing applications. You can extend standard interfaces with additional methods without physically altering the existing class libraries. You can extend .NET types and older COM/ActiveX® control types for new code without risk of breaking old applications that use these types. Prior to extension methods, in order to add functionality to classes and interfaces, you had a few options: * You could add the functionality to the source code, but this requires access to source code that may not be available. * You could use inheritance to inherit the functionality contained within one type into a new derived type, but not all types were inheritable. * You could re-implement the functionality from scratch. What I find odd about this is the assumption that one would want to add functionality to a class or interface. I mean, what's wrong with just calling, say, a static helper method? The example in the article, the
AlternateCase
method, seems ridiculous to implement as an extension method. Is this simply because the example is contrived? As the author points out: This is not a standard object-oriented concept; it is a specific Micros -
I was reading this on the MSDN site: A new feature made available in Visual Basic 2008, however, lets you extend any existing type's functionality, even when a type is not inheritable. And these extension methods play a crucial role in the implementation of LINQ. Many types that already exist can't be easily updated without breaking existing code. An example of this is the interface IEnumerable(Of T). In order to support LINQ, new methods had to be added to this interface, but changing the interface by adding new methods would break compatibility with existing consumers. Adding a new interface was a possibility, but creating a new interface to supplement the existing IEnumerable(Of T) interface would have appeared to be an odd design. What was needed was a way to extend existing types with new functionality without changing the existing contract. Is this true? That extension methods were added for the purpose of supporting Linq? The article[^] also makes some wierd points: Extension methods allow you to add functionality to a type that you don't want to modify, thus avoiding the risk of breaking code in existing applications. You can extend standard interfaces with additional methods without physically altering the existing class libraries. You can extend .NET types and older COM/ActiveX® control types for new code without risk of breaking old applications that use these types. Prior to extension methods, in order to add functionality to classes and interfaces, you had a few options: * You could add the functionality to the source code, but this requires access to source code that may not be available. * You could use inheritance to inherit the functionality contained within one type into a new derived type, but not all types were inheritable. * You could re-implement the functionality from scratch. What I find odd about this is the assumption that one would want to add functionality to a class or interface. I mean, what's wrong with just calling, say, a static helper method? The example in the article, the
AlternateCase
method, seems ridiculous to implement as an extension method. Is this simply because the example is contrived? As the author points out: This is not a standard object-oriented concept; it is a specific MicrosSo they've deprecated the
sealed
keyword too, then? :confused:cheers, Chris Maunder
CodeProject.com : C++ MVP
-
So they've deprecated the
sealed
keyword too, then? :confused:cheers, Chris Maunder
CodeProject.com : C++ MVP
Chris Maunder wrote:
So they've deprecated the sealed keyword too, then?
If I understand this all correctly, yes: ...but classes are sometimes marked NotInheritable to prevent modification of their behavior through inheritance... You bring up a really good point. The purpose of "sealed" is precisely to prevent extending the class. Yet extension methods now allow "tinkering" with the behavior of the class. The way I read it, you can do exactly that with extension methods. So, imagine an assembly "overriding" methods in the StringBuilder class (which is sealed) to create a different storage mechanism. But your assembly, according to this: Existing applications that use the original type will see no difference doesn't see the new extension methods, and uses the original implementation. So, now what happens when you have .NET's StringBuilder using its storage mechanism and some third party assembly that used its own internal storage mechanism on a class that's being passed between you and them? I think "Danger, Danger, Will Robinson" is appropriate now. Maybe somebody that really understands this stuff can shed some light on this. Justin? Marc
-
I was reading this on the MSDN site: A new feature made available in Visual Basic 2008, however, lets you extend any existing type's functionality, even when a type is not inheritable. And these extension methods play a crucial role in the implementation of LINQ. Many types that already exist can't be easily updated without breaking existing code. An example of this is the interface IEnumerable(Of T). In order to support LINQ, new methods had to be added to this interface, but changing the interface by adding new methods would break compatibility with existing consumers. Adding a new interface was a possibility, but creating a new interface to supplement the existing IEnumerable(Of T) interface would have appeared to be an odd design. What was needed was a way to extend existing types with new functionality without changing the existing contract. Is this true? That extension methods were added for the purpose of supporting Linq? The article[^] also makes some wierd points: Extension methods allow you to add functionality to a type that you don't want to modify, thus avoiding the risk of breaking code in existing applications. You can extend standard interfaces with additional methods without physically altering the existing class libraries. You can extend .NET types and older COM/ActiveX® control types for new code without risk of breaking old applications that use these types. Prior to extension methods, in order to add functionality to classes and interfaces, you had a few options: * You could add the functionality to the source code, but this requires access to source code that may not be available. * You could use inheritance to inherit the functionality contained within one type into a new derived type, but not all types were inheritable. * You could re-implement the functionality from scratch. What I find odd about this is the assumption that one would want to add functionality to a class or interface. I mean, what's wrong with just calling, say, a static helper method? The example in the article, the
AlternateCase
method, seems ridiculous to implement as an extension method. Is this simply because the example is contrived? As the author points out: This is not a standard object-oriented concept; it is a specific MicrosExtension method doesn't really tinker with the class. They can't access instance variable, can't override existing method, and are accessible only if you are using the namespace they are are declared in. Basically it's just nice syntaxic sugar. LINQ could have do without them, but you had to have a way to write custom enumerate, select or do other operation. Extension method provide and easy way to provide such for any class, even third party class.
-
Extension method doesn't really tinker with the class. They can't access instance variable, can't override existing method, and are accessible only if you are using the namespace they are are declared in. Basically it's just nice syntaxic sugar. LINQ could have do without them, but you had to have a way to write custom enumerate, select or do other operation. Extension method provide and easy way to provide such for any class, even third party class.
Super Lloyd wrote:
can't override existing method
So, I can't override a method with an extension method unless I'm in the same namespace? Well, what's to prevent me from simply declaring my extension method in the "System" namespace? And even if there is a mechanism, the confusion of having some piece of code change the implementation sounds like a maintenance/readability nightmare. It's why I actually feel that AOP is a bad idea. But that raises another question--is it possible for the extension method to call the original implementation? Marc
-
Super Lloyd wrote:
can't override existing method
So, I can't override a method with an extension method unless I'm in the same namespace? Well, what's to prevent me from simply declaring my extension method in the "System" namespace? And even if there is a mechanism, the confusion of having some piece of code change the implementation sounds like a maintenance/readability nightmare. It's why I actually feel that AOP is a bad idea. But that raises another question--is it possible for the extension method to call the original implementation? Marc
Marc Clifton wrote:
So, I can't override a method with an extension method unless I'm in the same namespace?
Nope.
Marc Clifton wrote:
Well, what's to prevent me from simply declaring my extension method in the "System" namespace?
Doesn't matter; instance methods always take precedence over extension methods.
Marc Clifton wrote:
is it possible for the extension method to call the original implementation?
Yep.
Tech, life, family, faith: Give me a visit. I'm currently blogging about: No, Not I - A poem by Holocaust escapee, chief rabbi, and Messiah-follower Daniel Zion (audio) The apostle Paul, modernly speaking: Epistles of Paul Judah Himango
-
Super Lloyd wrote:
can't override existing method
So, I can't override a method with an extension method unless I'm in the same namespace? Well, what's to prevent me from simply declaring my extension method in the "System" namespace? And even if there is a mechanism, the confusion of having some piece of code change the implementation sounds like a maintenance/readability nightmare. It's why I actually feel that AOP is a bad idea. But that raises another question--is it possible for the extension method to call the original implementation? Marc
Extension method are normal method. Only the compiler can use them (not the runtime), as per the documentation: "In your code you invoke the extension method with instance method syntax. However, the intermediate language (IL) generated by the compiler translates your code into a call on the static method. Therefore, the principle of encapsulation is not really being violated. In fact, extension methods cannot access private variables in the type they are extending." elsewhere in the documentation: "You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself." As you can see, they are only syntaxic sugar. I like them, of course I still need to define in my static helper class, but I like to see the new utility method appear on the class I use! :-D (plus intellisense has a special symbol for them, in the combobox, so you know they are extension) Plus I confidently know I didn't break anything, they are just syntaxic sugar.
-
I was reading this on the MSDN site: A new feature made available in Visual Basic 2008, however, lets you extend any existing type's functionality, even when a type is not inheritable. And these extension methods play a crucial role in the implementation of LINQ. Many types that already exist can't be easily updated without breaking existing code. An example of this is the interface IEnumerable(Of T). In order to support LINQ, new methods had to be added to this interface, but changing the interface by adding new methods would break compatibility with existing consumers. Adding a new interface was a possibility, but creating a new interface to supplement the existing IEnumerable(Of T) interface would have appeared to be an odd design. What was needed was a way to extend existing types with new functionality without changing the existing contract. Is this true? That extension methods were added for the purpose of supporting Linq? The article[^] also makes some wierd points: Extension methods allow you to add functionality to a type that you don't want to modify, thus avoiding the risk of breaking code in existing applications. You can extend standard interfaces with additional methods without physically altering the existing class libraries. You can extend .NET types and older COM/ActiveX® control types for new code without risk of breaking old applications that use these types. Prior to extension methods, in order to add functionality to classes and interfaces, you had a few options: * You could add the functionality to the source code, but this requires access to source code that may not be available. * You could use inheritance to inherit the functionality contained within one type into a new derived type, but not all types were inheritable. * You could re-implement the functionality from scratch. What I find odd about this is the assumption that one would want to add functionality to a class or interface. I mean, what's wrong with just calling, say, a static helper method? The example in the article, the
AlternateCase
method, seems ridiculous to implement as an extension method. Is this simply because the example is contrived? As the author points out: This is not a standard object-oriented concept; it is a specific MicrosMarc Clifton wrote:
Is this true? That extension methods were added for the purpose of supporting Linq?
LINQ could have been done without it. For example:
var evens = from numbers where i % 2 == 0 select i;
compiles down to essentially something like this:
IEnumerable numbers = Extensions.Where(numbers, NumberIsEven(i));
NumberIsEven would be a compiler-generated method, Extensions.Where is a static method contained in the .NET framework.
Marc Clifton wrote:
Is this simply because the example is contrived?
Yes, I think so. I recently wrote a little forum spam cleaning tool and found extension methods quite handy. I wrote an extension method called IsSpam() that extended Windows.Forms.HtmlElement. The resulting code was quite cleaner and more natural than something without extension methods, e.g.
var spamElements = from browser.Document.All
where element.IsSpam()
select element;as opposed to to the .NET 2 version without extension methods or LINQ:
List<HtmlElement> spamElements = new List();
foreach(HtmlElement element in browser.Document.All)
{
if(!string.IsNullOrEmpty(element.InnerHtml) && MyUtilities.IsSpam(element.InnerHtml))
{
spamElements.Add(element);
}
}Marc Clifton wrote:
So, I can't help but feel that extension methods are a kludge that may have many side effects, including sabotaging maintainability and OOP practices.
Not at all. Languages like Ruby have had similar things for some time and they've proven quite useful. If extension methods could truly modify the internals of a class, e.g. modify private fields, override methods, that kind of thing, then I'd agree with you. But in reality, extension methods are nothing magical, they compile down to regular static functions and have no special powers beyond plain old static methods. They just provide for a more natural syntax, e.g. element.IsSpam() as opposed to Utilities.IsSpam(element).
Tech, life, family, faith: Give me a visit. I'm currently blogging about: No, Not I - A poem
-
Chris Maunder wrote:
So they've deprecated the sealed keyword too, then?
If I understand this all correctly, yes: ...but classes are sometimes marked NotInheritable to prevent modification of their behavior through inheritance... You bring up a really good point. The purpose of "sealed" is precisely to prevent extending the class. Yet extension methods now allow "tinkering" with the behavior of the class. The way I read it, you can do exactly that with extension methods. So, imagine an assembly "overriding" methods in the StringBuilder class (which is sealed) to create a different storage mechanism. But your assembly, according to this: Existing applications that use the original type will see no difference doesn't see the new extension methods, and uses the original implementation. So, now what happens when you have .NET's StringBuilder using its storage mechanism and some third party assembly that used its own internal storage mechanism on a class that's being passed between you and them? I think "Danger, Danger, Will Robinson" is appropriate now. Maybe somebody that really understands this stuff can shed some light on this. Justin? Marc
Extension methods don't let you change the internal behavior of a class. They also don't allow you to override a method provided by that class...if you declare an extension method that has the same signature as a "real" method your extension method is ignored.
Scott.
—In just two days, tomorrow will be yesterday. [Forum Guidelines] [Articles] [Blog]
-
Super Lloyd wrote:
can't override existing method
So, I can't override a method with an extension method unless I'm in the same namespace? Well, what's to prevent me from simply declaring my extension method in the "System" namespace? And even if there is a mechanism, the confusion of having some piece of code change the implementation sounds like a maintenance/readability nightmare. It's why I actually feel that AOP is a bad idea. But that raises another question--is it possible for the extension method to call the original implementation? Marc
You can't override an existing method at all, no matter what namespace you're in...even if you declare it in the System namespace. I think that restriction coupled with the fact that extension methods can't access and manipulate the internals of the class removes your other concerns.
Scott.
—In just two days, tomorrow will be yesterday. [Forum Guidelines] [Articles] [Blog]
-
I was reading this on the MSDN site: A new feature made available in Visual Basic 2008, however, lets you extend any existing type's functionality, even when a type is not inheritable. And these extension methods play a crucial role in the implementation of LINQ. Many types that already exist can't be easily updated without breaking existing code. An example of this is the interface IEnumerable(Of T). In order to support LINQ, new methods had to be added to this interface, but changing the interface by adding new methods would break compatibility with existing consumers. Adding a new interface was a possibility, but creating a new interface to supplement the existing IEnumerable(Of T) interface would have appeared to be an odd design. What was needed was a way to extend existing types with new functionality without changing the existing contract. Is this true? That extension methods were added for the purpose of supporting Linq? The article[^] also makes some wierd points: Extension methods allow you to add functionality to a type that you don't want to modify, thus avoiding the risk of breaking code in existing applications. You can extend standard interfaces with additional methods without physically altering the existing class libraries. You can extend .NET types and older COM/ActiveX® control types for new code without risk of breaking old applications that use these types. Prior to extension methods, in order to add functionality to classes and interfaces, you had a few options: * You could add the functionality to the source code, but this requires access to source code that may not be available. * You could use inheritance to inherit the functionality contained within one type into a new derived type, but not all types were inheritable. * You could re-implement the functionality from scratch. What I find odd about this is the assumption that one would want to add functionality to a class or interface. I mean, what's wrong with just calling, say, a static helper method? The example in the article, the
AlternateCase
method, seems ridiculous to implement as an extension method. Is this simply because the example is contrived? As the author points out: This is not a standard object-oriented concept; it is a specific MicrosMarc, Take a look at these two blog posts...they may help explain extension methods a bit better: C# 3.0 Extension Methods Follow Up[^] Generic Enum Parsing with Extension Methods[^] Rhino Mocks + Extension Methods + MVC == Crazy Delicious[^] The reality of extension methods is that when you write them, you really are just writing a static class of helper methods. The only difference is the use of the
this
keyword in front of the first parameter. You can access them using the extension syntax or through the helper class. In fact, if you look at the code in reflector, you will see that the compiler is actually accessinng the method through the static class just like you would normally do. The extension syntax is simply more syntatic sugar. The benefit of using extension methods starts to show by providing a more natural syntax for the helper methods. Your example ofTools.StringToUpper(s)
is actually good in that the natural way to think about this is I want to make the current string object's value upper case. Given this, it's more natural to see code like this (although in this case, the name makes it a bit awkward):string s = "this is a test";
s.StringToUpper();rather than code like this
string s = "this is a test";
s = Tools.StringToUpper(s);I'm not sure I agree with the statement that one is more readable than the other; I think they are both equally readable. However, I think the extension method "flows" better and shows the intent with slightly less code at the calling site.
Scott.
—In just two days, tomorrow will be yesterday. [
-
I was reading this on the MSDN site: A new feature made available in Visual Basic 2008, however, lets you extend any existing type's functionality, even when a type is not inheritable. And these extension methods play a crucial role in the implementation of LINQ. Many types that already exist can't be easily updated without breaking existing code. An example of this is the interface IEnumerable(Of T). In order to support LINQ, new methods had to be added to this interface, but changing the interface by adding new methods would break compatibility with existing consumers. Adding a new interface was a possibility, but creating a new interface to supplement the existing IEnumerable(Of T) interface would have appeared to be an odd design. What was needed was a way to extend existing types with new functionality without changing the existing contract. Is this true? That extension methods were added for the purpose of supporting Linq? The article[^] also makes some wierd points: Extension methods allow you to add functionality to a type that you don't want to modify, thus avoiding the risk of breaking code in existing applications. You can extend standard interfaces with additional methods without physically altering the existing class libraries. You can extend .NET types and older COM/ActiveX® control types for new code without risk of breaking old applications that use these types. Prior to extension methods, in order to add functionality to classes and interfaces, you had a few options: * You could add the functionality to the source code, but this requires access to source code that may not be available. * You could use inheritance to inherit the functionality contained within one type into a new derived type, but not all types were inheritable. * You could re-implement the functionality from scratch. What I find odd about this is the assumption that one would want to add functionality to a class or interface. I mean, what's wrong with just calling, say, a static helper method? The example in the article, the
AlternateCase
method, seems ridiculous to implement as an extension method. Is this simply because the example is contrived? As the author points out: This is not a standard object-oriented concept; it is a specific MicrosIn some ways I do agree. However, if the programmers abuses this technology, then just simply means that those programmers did not design their solution correctly. Take the following in consideration (Just an example): // This is a normal way to print out hello world. // Let me use a static class that does this for me. (again, just an example.) public void Main(string[] args) { Console.WriteLine("Hello World."); } ----------- // The normal way. public static class StringHelper { public static void WriteToConsole(string str) { Console.WriteLine(str); } } public void Main(string[] args) { // Here I used the static class directly. StringHelper.WriteToConsole("Hello World."); } ----------- // The extention way. public static class StringHelper { public static void WriteToConsole(this string str) { Console.WriteLine(str); } } public void Main(string[] args) { // Here I'm using the extention. "Hello World.".WriteToConsole(); } So as you can see.. I believe that extention methods is nothing more than just away to help better your code. If you abuse this, then simply, it means that you can not design your solution correctly. I have used extention methods a lot of times with MonoRail's testing and it works much easier and much more friendlier than calling a static class over and over again.
Assumption is the mother of all f*ck ups. (^_^)
-
Marc, Take a look at these two blog posts...they may help explain extension methods a bit better: C# 3.0 Extension Methods Follow Up[^] Generic Enum Parsing with Extension Methods[^] Rhino Mocks + Extension Methods + MVC == Crazy Delicious[^] The reality of extension methods is that when you write them, you really are just writing a static class of helper methods. The only difference is the use of the
this
keyword in front of the first parameter. You can access them using the extension syntax or through the helper class. In fact, if you look at the code in reflector, you will see that the compiler is actually accessinng the method through the static class just like you would normally do. The extension syntax is simply more syntatic sugar. The benefit of using extension methods starts to show by providing a more natural syntax for the helper methods. Your example ofTools.StringToUpper(s)
is actually good in that the natural way to think about this is I want to make the current string object's value upper case. Given this, it's more natural to see code like this (although in this case, the name makes it a bit awkward):string s = "this is a test";
s.StringToUpper();rather than code like this
string s = "this is a test";
s = Tools.StringToUpper(s);I'm not sure I agree with the statement that one is more readable than the other; I think they are both equally readable. However, I think the extension method "flows" better and shows the intent with slightly less code at the calling site.
Scott.
—In just two days, tomorrow will be yesterday. [
I actually find the code with the extension method more readable. Actually, I think that for C# readability is one of the top priorities. Of course, we have been warned about extension methods, and it's clear that we shouldn't use them too often.
-
I actually find the code with the extension method more readable. Actually, I think that for C# readability is one of the top priorities. Of course, we have been warned about extension methods, and it's clear that we shouldn't use them too often.
tec-goblin wrote:
I actually find the code with the extension method more readable.
I do as well. To me it provides a more natural syntax.
tec-goblin wrote:
Actually, I think that for C# readability is one of the top priorities.
This really should be the goal for any developer, and isn't so much a factor of the language.
tec-goblin wrote:
Of course, we have been warned about extension methods, and it's clear that we shouldn't use them too often.
Warned by who? I think the biggest problem will be the potential for abuse by new/inexperienced programmers...but that is the case for almost any language construct.
Scott.
—In just two days, tomorrow will be yesterday. [Forum Guidelines] [Articles] [Blog]
-
Chris Maunder wrote:
So they've deprecated the sealed keyword too, then?
If I understand this all correctly, yes: ...but classes are sometimes marked NotInheritable to prevent modification of their behavior through inheritance... You bring up a really good point. The purpose of "sealed" is precisely to prevent extending the class. Yet extension methods now allow "tinkering" with the behavior of the class. The way I read it, you can do exactly that with extension methods. So, imagine an assembly "overriding" methods in the StringBuilder class (which is sealed) to create a different storage mechanism. But your assembly, according to this: Existing applications that use the original type will see no difference doesn't see the new extension methods, and uses the original implementation. So, now what happens when you have .NET's StringBuilder using its storage mechanism and some third party assembly that used its own internal storage mechanism on a class that's being passed between you and them? I think "Danger, Danger, Will Robinson" is appropriate now. Maybe somebody that really understands this stuff can shed some light on this. Justin? Marc
Marc Clifton wrote:
Yet extension methods now allow "tinkering" with the behavior of the class.
Extension methods cannot change existing behaviour. It is purely additive. And as Scott pointed out if you name an extension method after a real one it will be ignored.
Marc Clifton wrote:
So, imagine an assembly "overriding" methods in the StringBuilder class
You can't do that with extension methods.
Marc Clifton wrote:
So, now what happens when you have .NET's StringBuilder using its storage mechanism and some third party assembly that used its own internal storage mechanism on a class that's being passed between you and them?
Extension methods can't change storage mechanism. As the name suggests you only get to supply methods, not ways of storage. Extension methods only have access to public members on the class also, so they can't see what is inside either.
Upcoming FREE developer events: * Glasgow: SQL Server Managed Objects AND Reporting Services ... My website
-
Super Lloyd wrote:
can't override existing method
So, I can't override a method with an extension method unless I'm in the same namespace? Well, what's to prevent me from simply declaring my extension method in the "System" namespace? And even if there is a mechanism, the confusion of having some piece of code change the implementation sounds like a maintenance/readability nightmare. It's why I actually feel that AOP is a bad idea. But that raises another question--is it possible for the extension method to call the original implementation? Marc
Marc Clifton wrote:
the confusion of having some piece of code change the implementation sounds like a maintenance/readability nightmare
It CANNOT change the implementation. It isn't designed to do that. It is syntactic sugar for calling static helper methods only. Nothing more. Marc, you are usually very well informed but I think you've got the wrong end of the stick on this one and just gone off and ranted about it before seeing the full picture.
Upcoming FREE developer events: * Glasgow: SQL Server Managed Objects AND Reporting Services ... My website
-
Marc, Take a look at these two blog posts...they may help explain extension methods a bit better: C# 3.0 Extension Methods Follow Up[^] Generic Enum Parsing with Extension Methods[^] Rhino Mocks + Extension Methods + MVC == Crazy Delicious[^] The reality of extension methods is that when you write them, you really are just writing a static class of helper methods. The only difference is the use of the
this
keyword in front of the first parameter. You can access them using the extension syntax or through the helper class. In fact, if you look at the code in reflector, you will see that the compiler is actually accessinng the method through the static class just like you would normally do. The extension syntax is simply more syntatic sugar. The benefit of using extension methods starts to show by providing a more natural syntax for the helper methods. Your example ofTools.StringToUpper(s)
is actually good in that the natural way to think about this is I want to make the current string object's value upper case. Given this, it's more natural to see code like this (although in this case, the name makes it a bit awkward):string s = "this is a test";
s.StringToUpper();rather than code like this
string s = "this is a test";
s = Tools.StringToUpper(s);I'm not sure I agree with the statement that one is more readable than the other; I think they are both equally readable. However, I think the extension method "flows" better and shows the intent with slightly less code at the calling site.
Scott.
—In just two days, tomorrow will be yesterday. [
string s = "this is a test"; s.StringToUpper();
Nothing against extension methods, but I don't actually agree that this example is a good one. If extension methods are just a cosy way of making static helpers look like instance methods on the class in question, one thing they should surely never do is change the semantics of working with that class? Your code sample makes it look like string is not immutable. I suppose the readability is arguable, but it is certainly confusing to people unfamiliar with the class being extended and could lead to bugs being introduced elsewhere, especially on classes less well known or in third party libraries. The following, for example, wouldn’t behave as expected.string s = "this is a test"; s.StringToUpper(); s.Trim();
-
Marc Clifton wrote:
Is this true? That extension methods were added for the purpose of supporting Linq?
LINQ could have been done without it. For example:
var evens = from numbers where i % 2 == 0 select i;
compiles down to essentially something like this:
IEnumerable numbers = Extensions.Where(numbers, NumberIsEven(i));
NumberIsEven would be a compiler-generated method, Extensions.Where is a static method contained in the .NET framework.
Marc Clifton wrote:
Is this simply because the example is contrived?
Yes, I think so. I recently wrote a little forum spam cleaning tool and found extension methods quite handy. I wrote an extension method called IsSpam() that extended Windows.Forms.HtmlElement. The resulting code was quite cleaner and more natural than something without extension methods, e.g.
var spamElements = from browser.Document.All
where element.IsSpam()
select element;as opposed to to the .NET 2 version without extension methods or LINQ:
List<HtmlElement> spamElements = new List();
foreach(HtmlElement element in browser.Document.All)
{
if(!string.IsNullOrEmpty(element.InnerHtml) && MyUtilities.IsSpam(element.InnerHtml))
{
spamElements.Add(element);
}
}Marc Clifton wrote:
So, I can't help but feel that extension methods are a kludge that may have many side effects, including sabotaging maintainability and OOP practices.
Not at all. Languages like Ruby have had similar things for some time and they've proven quite useful. If extension methods could truly modify the internals of a class, e.g. modify private fields, override methods, that kind of thing, then I'd agree with you. But in reality, extension methods are nothing magical, they compile down to regular static functions and have no special powers beyond plain old static methods. They just provide for a more natural syntax, e.g. element.IsSpam() as opposed to Utilities.IsSpam(element).
Tech, life, family, faith: Give me a visit. I'm currently blogging about: No, Not I - A poem
Judah Himango wrote:
compiles down to essentially something like this:
So, the implication is that Linq is syntactical frosting on top of extension methods, which is syntactical sugar? [edit] Furthermore, the implication is that Linq could be done without extension methods, in contradiction to what the author in the first article I link to states [/edit] Marc
-
Marc Clifton wrote:
Yet extension methods now allow "tinkering" with the behavior of the class.
Extension methods cannot change existing behaviour. It is purely additive. And as Scott pointed out if you name an extension method after a real one it will be ignored.
Marc Clifton wrote:
So, imagine an assembly "overriding" methods in the StringBuilder class
You can't do that with extension methods.
Marc Clifton wrote:
So, now what happens when you have .NET's StringBuilder using its storage mechanism and some third party assembly that used its own internal storage mechanism on a class that's being passed between you and them?
Extension methods can't change storage mechanism. As the name suggests you only get to supply methods, not ways of storage. Extension methods only have access to public members on the class also, so they can't see what is inside either.
Upcoming FREE developer events: * Glasgow: SQL Server Managed Objects AND Reporting Services ... My website
Thanks Colin (and everyone else). That helps clarify a few things. I wish the articles on MSDN would say it as clearly and well as you and the other CPians have here. Marc
-
tec-goblin wrote:
I actually find the code with the extension method more readable.
I do as well. To me it provides a more natural syntax.
tec-goblin wrote:
Actually, I think that for C# readability is one of the top priorities.
This really should be the goal for any developer, and isn't so much a factor of the language.
tec-goblin wrote:
Of course, we have been warned about extension methods, and it's clear that we shouldn't use them too often.
Warned by who? I think the biggest problem will be the potential for abuse by new/inexperienced programmers...but that is the case for almost any language construct.
Scott.
—In just two days, tomorrow will be yesterday. [Forum Guidelines] [Articles] [Blog]
>>Warned by who? I think the biggest problem will be the potential for abuse by new/inexperienced programmers...but that is the case for almost any language construct. I have seen it in the explanation of the new features in MSDN articles, that extension methods should be used with caution. As for new/inexperienced programmers, my experience is that they tend to be familiarised only with the basic things that are common in java and c#, and most won't even think of using extension methods. Then they might discover them, they might use them once or twice erroneously, but that's ok and natural.