Software Development

Crazy Extension Methods Redux (with Oxygene)

Back in April I blogged about a crazy thing you can do with extension methods in C#3.0. At the time I was adamant that it was a bad idea. I still think it is a bad idea, however, my thoughts have evolved a little since then and I have, possibly a solution to my hesitance to use said crazy feature.

So, if you can’t be bothered to click the link, here is a quick recap. You can create an extension method and call it on a null reference and it will NOT throw a NullReferenceException like a real method call would. At the time I was saying it was not best practice because it breaks the semantics of the dot operator which is used for member access.

Last night, I attended an excellent talk by Barry Carr on Oxygene, an Object Pascal based language that targets the .NET Framework. Oxygene has a very interesting feature, it has a special operator for dealing with calls on a reference that might be null. If that language can do it, what’s so wrong with the functionality that Extension methods potentially give? Semantics. Notice that I said that Oxygene has “a special operator”. It doesn’t use the dot operator. The dot operator still breaks if the reference is null. It has a colon operator. In this case if the reference is null (or nil as it is called in Oxygene) then the call to the method doesn’t happen. No exception is thrown.

For example. Here is the code with the regular dot operator:

class method ConsoleApp.Main;
var
  myString: String := nil;
begin
  Console.WriteLine('The string length is {0}', myString.Length);
  Console.ReadLine();
end;

And the result is that the NullReferenceException is thrown:

NullReferenceException

Here is the code with the colon operator:

class method ConsoleApp.Main;
var
  myString: String := nil;
begin
  Console.WriteLine('The string length is {0}', myString:Length);
  Console.ReadLine();
end;

And the result is that the program works, it just didn’t call the property Length as there was nothing to call it on:

Result

At this point I really would like to show you what this looks like in Reflector to show you what is going on under the hood, however, I get a message that says “This item is obfuscated and can not be translated” and the code afterwards isn’t quite right. However, the crux of it is like this in C#:

int? length;

if (myString != null)

length = myString.Length;

Console.WriteLine(“The string length is {0}”, length);

Now, back to these extension methods. After seeing this I was thinking that perhaps my total unacceptablity of allowing a null reference to be used with an extension method was perhaps incorrect. In a normal situation with an accidental null reference exception being used the NullReferenceException wouldn’t be thrown at the point of the method call (after all, the null reference is actually being passed in as the first parameter in an extension method), but somewhere in the method itself. Normal good practice would place a guard block at the start of the method so that it would be caught immediately.

However, what if you wanted to create similar functionality to the colon operator in Oxygene and have it ignore the null reference and do nothing? Well, my advice would be to create a naming convention for your extension methods to show that null references will be ignored. That way you can get the functionality with a slight semantic fudge of the dot operator. Of course, you still have to do the work and set up guard blocks to handle the null situation yourself in the extension method.

Here’s an example:

class Program
{
    static void Main(string[] args)
    {
        string myString = null;
        Console.WriteLine("The string length is {0}", myString.NullableLength());
        Console.ReadLine();
    }
}

public static class MyExtensions
{
    public static int? NullableLength(this string target)
    {
        if (target == null)
            return null;
        return target.Length;
    }
}
Misc

Crazy Extension Method

Here is an example of a crazy extension method that alters the semantics of method calling.

First the extension method:

public static class MyExtensions
{
    public static bool IsNullOrEmpty(this string target)
    {
        return string.IsNullOrEmpty(target);
    }
}

Instead of calling the static method IsNullOrEmpty() on string, we are turning it around to allow it to be called on a string type like an instance method. However, as you can probably tell, it may be called when the reference to the string is null. Normally this would result in an exception to say that you are attempting to call a method on a null value. However, this is an extension method and it actually works with nulls! This is probably not the best idea in the world, to be diplomatic about it.

Here is some calling code:

string a = null;
Console.WriteLine(a.IsNullOrEmpty());

Normally, an exception will be thrown if IsNullOrEmpty() is a real method. However, it isn’t in this case and the application happily writes “True” to the console.

 

Software Development

Mixins in C# 3.0

This is something I’ve been mulling around in my head for a few days now. “Out of the box” C# 3.0 does not support mixins, but I think you can get some of the abilities of a mixin with what is there already.

Firstly I should probably explain what a mixin is. A mixin is a class that provides some specific functionality that is to be inherited by a derived class, but it does not have a specialisation (kind-of) relationship with the derived class.

The example that I have is of a class hierarchy representing different types of animal.The base class is Animal, derived from that is Avian and Mammal. Derived from Avian is Parrot, Penguin and Chicken. Derived from Mammal is Dog, Cat, Whale and Bat.

Class-Diagram-1

These animals all have various methods of locomotion. Some can swim, some can run and others can fly. However, as you can see there is no obvious relationship through the base class. It might seem at first glance while designing the class hierarchy that an avian should be able to fly. It is, after all, the first thing that springs to mind when thinking about how birds get from one place to another. But what about flightless birds such as the Dodo? Similarly, don’t all mammals run? No, there are many that live in the sea.

As you can see, adding methods for flight on the Avian base class or running on the Mammal base class don’t work in all cases. This is where mixins come into play.

Mixins can, in this example, provide the functionality for flight, running or swimming, or any other form of locomotion by having the appropriate class inherit the functionality. However, C# does not permit multiple inheritance. You can inherit from one base class only in C#.

But, you can implement multiple interfaces. At this point you are probably thinking “Ah-hah! But interfaces don’t have any functionality”. True, you won’t get too far if you just use some interfaces on the classes. But it is the first step.

Class-Diagram-2

With C# 3.0 came the introduction of Extension Methods and they can be applied, not only to classes but, also, to interfaces. Extension Methods provide additional functionality on an existing class without modifying the class. (You can read more about Extension Methods here). It then becomes possible to create a static helper class for specific functionality that defines the extension methods. Because the classes implement the interface (even if the actual interface doesn’t contain any methods or properties to implement) it will pick up all the extension methods also.

public  static  class SwimMixin
{
    public static void Swim(this ISwim target)
    {
        // Perform Swim functionality on the target
    }
}

This provides very limited mixin functionality. The imitation mixin cannot hold any data of its own which means that so long as the imitation mixin can get away without adding attribute information of its own then it is still useful.

If you need to have the mixin hold its own data then I can, at present, see a number of potential solutions to this problem. Unfortunately no solution is terribly elegant, nor are they problem free.

The first is to use a lookup keyed on weak references to the actual instantiated class with the result of the lookup returning the data needed for the Mixin. The reason for the weak reference is to ensure that the instances of the class get cleared out and are not retained by the imitation mixin. Remember the imitation mixin is built out of a static class so it won’t go out of scope and get cleared up by the garbage collector and everything it holds will stay around as long as the application is running. The main problem with this approach is that as the number of actual instantiated classes increases the lookups get larger and will naturally slow down. Also, some mechanism for clearing out the keys and data that are no longer required has to be implemented as the actual objects are garbage collected.

The second is to use the interface that the extension method is using to provide a method that can be used by the imitation mixin to access its data. This would mean that the actual  instance of the class would have to hold onto some additional data on behalf of the imitation mixin, which negates part of its usefulness.

The third is to create a base class for that all classes that may wish to use a mixin inherit from. This base class can contain “instance” data, in a hashtable keyed on the mixin type (for instance) on behalf of the mixin itself. This would, unfortunately, mean that the data is exposed and render encapsulation useless. It also causes a small hit each time a mixin method needs access to its “instance” data. Naturally, if you are inheriting from an existing framework class you won’t have the option of putting in a base class to hold the mixin data.

Class-Diagram-3

It isn’t too hard to see that it may be possible in the future to have mixin behaviour built directly into the language as we are already part of the way there. In the meantime some limited functionality is available which can be extended to include instance data for the mixin itself with some extra work, but it isn’t without its problems.

Misc

Extensions Methods

I’ve been looking at more of the language enhancements in C# 3.0. In this post I’m going to look at Extensions.

There have been many times went a class has needed to be extended, but the additional code just doesn’t sit right on the class itself. In that case a utility or helper class is created to help carry out these mundane tasks without impacting the main class the helper operates on. It may be because the method requires access to classes that would tightly couple the main class to others.

It is important to remember that the extension method, like any method on a helper or utility class, cannot access the private or protected members of the class it is helping.

For example, take the children’s game Fizz-Buzz which seems to be undergoing a resurgence at the moment. The rules for the method are simple. The program counts from 1 to 100 replacing any value that is divisible by 3 with Fizz and any value that is divisible by 5 with Buzz. If a value happens to be divisible by both 3 and 5 then the output is FizzBuzz. For any other value the number is output.

First here is the version without the extensions:

public static class FizzBuzzHelper
{
    public static string FizzBuzz(int number)
    {
        if ((number % 5) == 0)
        {
            if ((number % 3) == 0)
                return "FizzBuzz";
            return "Buzz";
        }
        if ((number % 3) == 0)
        {
            return "Fizz";
        }
        return number.ToString();
    }
}

class Program
{
    static void Main(string[] args)
    {
        for (int i = 1; i <= 100; i++)
        {
            Console.WriteLine(FizzBuzzHelper.FizzBuzz(i));
        }
        Console.ReadLine();
    }
}

And now the version with the extensions:

public static class FizzBuzzHelper
{
    public static string FizzBuzz(this int number)
    {
        if ((number % 5) == 0)
        {
            if ((number % 3) == 0)
                return "FizzBuzz";
            return "Buzz";
        }
        if ((number % 3) == 0)
        {
            return "Fizz";
        }
        return number.ToString();
    }
}

class Program
{
    static void Main(string[] args)
    {
        for (int i = 1; i <= 100; i++)
        {
            Console.WriteLine(i.FizzBuzz());
        }
        Console.ReadLine();
    }
}

There aren’t actually that many changes (and the example is somewhat trivial).

First, in the extension method, the this keyword is placed before the parameter. It indicates that the extension will go on the int (or rather the Int32) class.

Second, when the extension method is called there is no reference to the utility class. It is simply called as it it were a method on the class (in this case Int32). Also, note that the parameter is not needed because it is implied by the object on which the extension method is applied.

Lutz Roeder’s reflector is already conversant with extension methods so the compiler trickery cannot be seen in the C# view of the method. However, the IL reveals that deep down it is just making the call as before. The following is the extension version:

L_0007: call string ConsoleApplication3.FizzBuzzHelper::FizzBuzz(int32)
L_000c: call void [mscorlib]System.Console::WriteLine(string)

And this is the old-style helper method call:

L_0007: call string ConsoleApplication3.FizzBuzzHelper::FizzBuzz(int32)
L_000c: call void [mscorlib]System.Console::WriteLine(string)

They are identical. So, how does the compiler tell what it needs to be doing?

The method header for the regular helper method:

.method public hidebysig static string FizzBuzz(int32 number) cil managed
{

The method header for the extension method:

.method public hidebysig static string FizzBuzz(int32 number) cil managed { .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor()

And that’s it. C# just hides the need for the ExtensionAttribute. In VB the attribute needs to be explicitly declared on the method.

Intellisense also helps out with extensions. Each extension method appears in the intellisense on the object it is extending. To ensure that the developer is aware that it is an extension the icon in the list has a blue arrow and the tool tip is prefixed with “(extension)”

orcas-extensions-intellisense

It is also possible to create extension methods that take more than one parameter. For example:

public static class PasswordHashHelper
{
    public static byte[] HashPassword(this string password, byte[] salt)
    {
        // Implementation here
    }
}

It is important to note that the this modifier can only be placed on the first parameter. To do otherwise would generate the compiler error “Method ‘{method name}’ has a parameter modifier ‘this’ which is not on the first parameter”

The above multi parameter extension method can then be used like this:

byte[] hashedPassword = plainTextPassword.HashPassword(salt);

NOTE: This entry was rescued from the Google Cache. The original date was Thursday, 15th March, 2007.