Thursday, June 19, 2014

Extension Methods

Intro

What is the airspeed velocity of an unladen swallow? African AND European.

Oh wait, wrong question. What I meant was, what are extension methods? Extension methods allow you, the humble developer, to add methods to existing types. You can do this without inheritance and without modifying the source class.

Example

I think the best way to illustrate the concept is with an example. We will extend the int class for the sake of dice rolling. Specifically, I want to be able to roll 2 x-sided die at the same time. I know this seems like a waste of effort to use an extension method, but too bad; it's my blog! So, we'll extend Integer to have a DoubleDieRoll() method which returns a Tuple<int, int> that is 2 rolls of a die with x sides, where x is the source integer. So for example, if I were to call 6.DoubleDieRoll(); I would expect to receive a 2-part result tuple that contains 2 random numbers between 1 and 6. Believe it or not, this is quite easy to do in .net. Fire up a .net project of your favorite type (winforms, xaml, webforms, mvc, whatever) and add a class called GameExtensions. In the sample code below I've created an mvc project ccalled BlogExtensionMethods. Create yourself a new class named "GameExtensions" (note that this name is purposely meaningless, to illustrate that the name of the class doesn't matter). Here's the code for my class:

using System;

namespace BlogExtensionMethods
{
    public static class GameExtensions
    {
        public static Tuple<int, int> DoubleDieRoll(this int val)
        {
            Random rnd = new Random();
            var roll1 = rnd.Next(1, val);
            var roll2 = rnd.Next(1, val);
            return new Tuple<int, int>(roll1, roll2);
        }
    }
}


As you can see, we have a single static class name GameExtensions. Within this class we have a single static method named DoubleDieRoll. The key part of the method is the parameter. the parameter "this int val" means that our method DoubleDieRoll will work on the int class. The body of the method is nothing special, but it does illustrate returning a tuple of int, int. So, key points:
  1. static class
  2. static method
  3. single parameter with the keyword this, the data type we're extending, and a name for the parameter (name doesn't matter).

Now let's see how to call the spiffy new method:

        public string Roll2Die()
        {
            var dieRolls = 20.DoubleDieRoll();
            return String.Format("die roll1: {0}, die roll2: {1}", dieRolls.Item1, dieRolls.Item2);
        }



Cool huh? You can call this on any old int value. In the above code we're calling 20.DoubleDieRoll(). It's pretty fun, and you even get intellisense on your call within the IDE! You'll get back 2 random rolls of a 20-sided die with the above code.

Pitfalls

This stuff is pretty fun, but guess what? There are a lot of people that recommend you use extension methods very judiciously if at all. The reasoning is that it can get kind of confusing if in some projects you have methods on pre-canned classes that don't exist in other projects, such as the odd DoubleDieRoll we defined above for the int class. I must confess that I've never used extension methods, partially for this reason. However like any other tool, I'm sure it has it's uses and if you try hard enough you just might find one yourself.

Resources

Extension Methods, from the c# Programming Guide on MSDN

No comments:

Post a Comment