Saturday, October 15, 2011

NETMF Extension Methods

If you come from desktop development with the full .NET Framework then you're probably familiar with extension methods.  Extension methods allow us to write functions that extend existing classes for which we may not have the source.

For example, suppose for our project we know we will commonly need to convert strings to an array of their ASCII character codes.  We could write a function that accepts a string parameter and returns an integer array but a cleaner alternative would be an extension method.

var someString = "ABC";

// Using a function it would look like this...
var asciiCodes = ConvertStringToAsciiCodesArray(someString);

// Using an extension method it would look like this...
var asciiCodes = someString.ToAsciiCodesArray();

However, if you have created extension methods before and you just dive in and try to create them in NETMF as you normally would then you'll either quickly assume they just aren't available in NETMF or you'll end up here.  Creating extension methods in NETMF as you normally would will result in the following error when you try to use the this keyword.
Cannot define a new extension method because the compiler required type 'System.Runtime.CompilerServices.ExtensionAttribute' cannot be found. Are you missing a reference to System.Core.dll?
Then you'll probably look for System.Core to reference and won't be able to find it...  You won't.  Don't need it.  This is a mostly useless error.  But what you do need to do is demonstrated in the following code sample.  Pay special attention to the first block of code that is used to enable extension methods in NETMF.

using Microsoft.SPOT;

// Required for NETMF to recognized extension methods
namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute { }
}

// Extension methods for string - note that it must be static
// You'll probably want to put this in it's own file.
public static class StringExtensions
{
    // Method to convert a string into an array of it's ascii character codes.  Note that it must also be static.
    public static int[] ToAsciiCodesArray(this string me)
    {
        // Make sure a null isn't passed in.
        if (me == null) return null;

        var chars = me.ToCharArray();
        var asciiCodes = new int[me.Length];
        for(var ndx = 0; ndx < me.Length; ndx++)
        {
            asciiCodes[ndx] = chars[ndx];
        }
        return asciiCodes;
    }
}

namespace ExtensionMethodsTutorial
{
    public class Program
    {
        public static void Main()
        {
            // Let's test out our new ToAsciiArray() extension method;
            var someString = "ABC";
            foreach (var asciiCode in someString.ToAsciiCodesArray())
            {
                Debug.Print(asciiCode.ToString());
            }
            return;
        }
    }
}

I hope this gets you going creating extension methods in NETMF. Feel free to contact me if you have any other problems with extension methods or NETMF in general.

CREDIT:  I first found the solution to this problem here but thought it deserved a more public write-up.