Scott Hanselman has a post about a user who doesn’t get what is cool about Ruby.
In the post you can find the below example that compares Java and Ruby in terms of code readability.
The Java code:
new Date(new Date().getTime() - 20 * 60 * 1000)
The Ruby code:
20.minutes.ago
The article was interesting but what really caught my attention was some comments from C# programmers who showed how, in a few lines of code, you can mimic the Ruby syntax in C# using extension methods.
The new version of C#, shipped with the Orcas release of Visual Studio, has a new feature called extension methods. Extension methods were added to the .Net languages to support LINQ and they provide a way to attach methods to classes without changing their code.
The below code is copied and modified from the comments of Ian Cooper in the aforementioned blog post.
public static class TimeExtensions { public static TimeSpan Minutes(this int numberOfMinutes) { return new TimeSpan(0, numberOfMinutes, 0); } public static DateTime Ago(this TimeSpan numberOfMinutes) { return DateTime.Now.Subtract(numberOfMinutes); } }
In the above code we defined a class, called TimeExtensions
, which contains two extension methods. Notice the this
keyword on the left of the fist parameter (both methods take one parameter in the example code) of the methods. The this
keyword tells the C# compiler that a method is an extension method. The parameter annotated with the this
keyword is the object on which the extension method is called. If I am correct, the methods are not really added to the classes (you can’t find them via reflection), the compiler at-compile-time translates them into static method calls.
In our example the first method, called Minutes
, will be added to the int
class (probably via auto-boxing) and the second method, called Ago
, will be added to the TimeSpan
class.
Now, to use the extension methods that we defined above we have to import them using the using TimeExtensions
statement. This is a really good thing since the usage of extension methods is always explicit. You have to import them to use them and if you don’t want to use them you don’t import them.
using System; using TimeExtensions; public class HelloWorld { public static void Main() { Console.WriteLine( 20.Minutes().Ago() ); } }
20.Minutes().Ago()
is pretty close to 20.minutes.ago
🙂
For a nice tutorial about C# 3.0 extension methods see: New “Orcas” Language Feature: Extension Methods.
damn, this looks yummy!
Extensions look good, but what happens when people start adding extensions to security classes?
Hi Chris,
I am not a C# programmer and unfortunately I do not have a windows machine to try C# and see exactly how extension methods work.
From my understanding I can’t see how extension methods can affect the security of a program. It would be nice if you could give a concrete example to base our discussion.
Thank you for the comment and sorry for my late reply.
Well, While Extension Methods (EM) provide a useful machanism to add new functionality to an existing base types, it also adds lot of confusion, if lot of extesions are added to base types like string. If developers keeping adding more methods to base classes for every single requirement just becuase it improves the readability (string email; email.IsValid()) then don’t you think these all unnessary EMs clutter the code in the IDE (intellisense)
I think there are some good reasons we need it but extending base type is not really a good idea I guess.
What I suggest is using/creating Money (http://www.martinfowler.com/eaaCatalog/money.html) like classes for all your requirements 🙂
Regards,
…Ashok
extension methods are syntactic sugar around static method calls. The syntax fits well with ruby, but now in c# you must ask is this an extension method, or an actual method in the object? Adds confusion.
Hi Ashok,
I agree with you that EMs can be misused and that we should try to create domain specific objects instead of just adding new methods to general purpose classes like string.
Billie,
I don’t believe that extension methods add confusion because the user has to import them explicitly. Also you could have a visual indicator in your IDE. For example in Eclipse (I am a Java programmer) the static methods appear in italic fonts, so I suppose that in Visual Studio you could have a similar highlighting and because extension methods are actually static method they could also appear in italic fonts.