Wednesday, April 20, 2011

C# Abuse

 

So I just watched this video presentation by Jon Skeet about some of the edges of our understanding of the C# language.

In this blog post, he threw open the challenge to define three static methods such that the following code compiles:

static void Main() 
{
Foo<int>();
Foo<string>();
Foo<int?>();
}

While watching the video and playing around on my own, I came up with:

class Program
{
static void Foo<T>() { Console.WriteLine(typeof(T).Name); }

class Inner : Program
{
struct R<T> where T : class { }

static void Foo<T>(params R<T>?[] _) where T : class { Console.WriteLine(typeof(T).Name); }
static void Foo<T>(params T?[] _) where T : struct { Console.WriteLine(typeof(T).Name); }

static void Main()
{
Foo<int>();
Foo<string>();
Foo<int?>();
}
}
}

which prints out the correct result. The analysis of how this works is given brilliantly over at Jon’s blog!


The key is the inner class, which forces the compiler to first check signature suitability for the two methods defined therein, before allowing the base class to catch-all with the most generalized signature.


Figure 1


The same caveat that Jon specified in his blog applies – such code should *never* be written!