C# refcard now available (free) from DZone

Just a quick announcement. I’ve been working on a C# “refcard” with DZone, and it’s now available. It’s free to download after registration, and covers (briefly):

  • String escape sequences
  • Delegate and event syntax
  • Nullable value types
  • Syntax for generics
  • Extension methods
  • Query expressions

Obviously this isn’t meant to be a comprehensive guide to C#, but I picked topics which have elements of syntax which are easily forgotten. Hopefully you’ll find it useful – and a refcard on “Core .NET” will be following fairly soon.

DZone also has a discount on Manning books, including C# in Depth.

Thank you, JetBrains: dotTrace rocks

One thing I failed to mention in my post about making reflection perform better is how I optimised the rest of the code. It was always pretty obvious that the reflection side would start off as a bottleneck – but for the rest of the code, I’ve relied heavily on dotTrace. It’s from JetBrains, the same people who make ReSharper (without which I’d be considerably more frustrated with Visual Studio).

While there are certainly elements of dotTrace which I haven’t explored (and occasionally some results which have mystified me – such as a claim that the CPU spent 111 seconds in one particular method, when the whole trace was only 99 seconds long – I suspect some double-counting of recursion) it’s been really useful, and incredibly easy to get started with.

JetBrains gives MVPs free licences for both ReSharper and dotTrace, which obviously makes me predisposed towards warm, fuzzy feelings for them. Both of them are highly recommended though, and have saved me a lot of time.

Making reflection fly and exploring delegates

Background

I’ve recently been doing some optimisation work which has proved quite interesting in terms of working with reflection. My efforts porting Google’s Protocol Buffers are now pretty complete in terms of functionality, so I’ve been looking at improving the performance. The basic idea is that you specify your data types in a .proto file, and then generate C# from that. The generated C# allows you to manipulate the data, and serialize/deserialize it. When you generate the code, it can be optimised either for size or speed. The “small” code can end up being much smaller than the “fast” code – but it’s also significantly slower as it uses reflection when serializing and deserializing. My first rough-and-ready benchmark results (using a 130K data file based on Northwind) were slightly terrifying:

Operation Time (ms)
Deserialize (fast) 5.18
Serialize (fast) 3.96
Deserialize (slow) 429.49
Serialize (slow) 103.67

Far from all of this difference was due to reflection, but it was a significant chunk – and provided the most interesting and challenging optimisation. This post doesn’t show the actual Protocol Buffer code, but demonstrates the three steps I required to radically improve the performance of reflection. The examples I’ve used are chosen just for simplicity.

Converting MethodInfo into a delegate instance

There are lots of things you can do with reflection, obviously – but I’m primarily interested in calling methods, using the associated MethodInfo. This includes setting properties, using the results of the GetGetMethod and GetSetMethod methods of PropertyInfo. We’ll use String.IndexOf(char) as our initial example.

Normally when you’re calling methods with reflection, you call MethodInfo.Invoke. Unfortunately, this proves to be quite slow. If you know the signature of the method at compile-time, you can convert the method into a delegate with that signature using Delegate.CreateDelegate(Type, object, MethodInfo). You simply pass in the delegate type you want to create an instance of, the target of the call (i.e. what the method will be called on), and the method you want to call. It would be nice if there were a generic version of this call to avoid casting the result, but never mind. Here’s a complete example demonstrating how it works:

using System;
using System.Reflection;

public class Test
{
    static void Main()
    {
        MethodInfo method = typeof(string).GetMethod(“IndexOf”, new Type[]{typeof(char)});
       
        Func<char, int> converted = (Func<char, int>) Delegate.CreateDelegate
            (typeof(Func<char, int>), “Hello”, method);
       
        Console.WriteLine(converted(‘l’));
        Console.WriteLine(converted(‘o’));
        Console.WriteLine(converted(‘x’));
    }
}

This prints out 2, 4, and -1; exactly what we’d get if we’d called "Hello".IndexOf(...) directly. Now let’s see what the speed differences are…

We’re mostly interested in the time taken to go from the main calling code to the method being called, whether that’s with a direct method call, MethodInfo.Invoke or the delegate. To make IndexOf itself take as little time as possible, I tested it by passing in ‘H’ so it would return 0 immediately. As normal, the test was rough and ready, but here are the results:

Invocation type Stopwatch ticks per invocation
Direct 0.18
Reflection 120
Delegate 0.20

One important point is that I created a new parameter array for each invocation of the MethodInfo – obviously this is slightly costly in itself, but it mirrors real world usage. The exact numbers don’t matter, but the relative sizes are the important point: using a delegate invocation is only about 10% slower than direct invocation, whereas using reflection takes over 600 times as long. Of course these figures will depend on the method being called – if the direct invocation can be inlined, I’d expect that to make a significant difference in some cases. However, the benefit in converting reflection calls into delegate calls is obvious.

Now, what about if we wanted to vary the string we were calling IndexOf on?

Interlude: open and closed delegates

When you create a delegate directly in C# using a method group conversion, you (almost) always create an open delegate for static methods and a closed delegate for instance methods. To explain the difference between open and closed delegates, it’s best to start thinking of all methods as being static – but with instance methods having an extra parameter at the start to represent this. In fact, extension methods use exactly this model. Reality is more complicated than that due to polymorphism, but we’ll leave that to one side for the moment.

Going back to our String.IndexOf example, we can start thinking of the signature as being:

static int IndexOf(string target, char c)

At this point it’s easy to explain the difference between open and closed delegates: a closed delegate has a value which it implicitly passes in as the first argument, whereas with an open delegate you specify all the arguments when you invoke the delegate. The implicit first argument is represented by the Delegate.Target property. It’s null for open delegates – which is usually the case when you create a delegate directly in C#. Here’s a short program to demonstrate the difference when you create delegate instances using C# directly:

using System;

public class Test
{
    readonly string name;
   
    public Test(string name)
    {
        this.name = name;
    }
   
    public void Display()
    {
        Console.WriteLine(“Test; name={0}”, name);
    }
   
    static void StaticMethod()
    {
        Console.WriteLine(“Static method”);
    }
   
    static void Main()
    {
        Test foo = new Test(“foo”);
       
        Action closed = foo.Display; // closed.Target == foo
        Action open = StaticMethod;  // open.Target == null
       
        closed();
        open();
    }
}

Before we go back to reflection, I’ll clarify the “almost” I used earlier on. You can’t currently create an open delegate referring to an instance method in C# using method group conversions – but you can create a closed delegate referring to a static method, if it’s an extension method. This makes sense, as extension methods are a strange sort of half-way house between static methods and instance methods – they’re truly static methods which can be used as if they were instance methods. I’ve got an example on my C# in Depth site.

Creating open delegates with reflection

Even though C# doesn’t support all the possible combinations of static/instance methods and open/closed delegates directly, Delegate.CreateDelegate has overloads to let you do just that. The signature we used earlier (with parameters Type, object, MethodInfo) always creates a closed delegate. There’s another overload without the middle parameter – and that always creates an open delegate. We can easily modify our earlier example to let us call String.IndexOf(char) varying both the needle and the haystack, so to speak:

using System;
using System.Reflection;

public class Test
{
    static void Main()
    {
        MethodInfo method = typeof(string).GetMethod(“IndexOf”, new Type[]{typeof(char)});
       
        Func<string, char, int> converted = (Func<string, char, int>) Delegate.CreateDelegate
            (typeof(Func<string, char, int>), method);
       
        Console.WriteLine(converted(“Hello”, ‘l’));
        Console.WriteLine(converted(“Jon”, ‘o’));
        Console.WriteLine(converted(“Hello”, ‘n’));
    }
}

This prints 2, 1, -1, as if we’d called "Hello".IndexOf('l'), "Jon".IndexOf('o') and "Hello".IndexOf('n'). This can be a very powerful tool – in particular it’s crucial for my Protocol Buffers port: for a particular type, I can create a delegate which will set a property. I can keep that information around forever, and use the same delegate to set the property to different values on different instances of the type.

There’s just one more problem to overcome – and unfortunately this is where things get a little weird.

Adapting delegates for parameter and return types

Due to the way that the Protocol Buffer library works, I often need to call methods or set properties without knowing at compile-time what the parameter types are, or indeed the return type of the method. I can be confident that I’ll always call it with appropriate parameters, but I just don’t know what they’ll be ahead of time. Things are slightly better in terms of the type declaring the method – I know that at compile-time, although only as a generic type parameter. What I do know with confidence is the number of parameters (I’ll just specify a single parameter for our example), and whether or not the method will return a value (we’ll use an example which always returns a parameter).

What I need is a generic method which has a type parameter T representing the type which implements the method, and which returns a Func<T, object, object> – a delegate instance which lets me pass the target and the argument value, and which will call the method and then return the value in a weakly typed manner. So we’d like this kind of program to work:

using System;
using System.Reflection;
using System.Text;

public class Test
{
    static void Main()
    {
        MethodInfo indexOf = typeof(string).GetMethod(“IndexOf”, new Type[]{typeof(char)});
        MethodInfo getByteCount = typeof(Encoding).GetMethod(“GetByteCount”, new Type[]{typeof(string)});
       
        Func<string, object, object> indexOfFunc = MagicMethod<string>(indexOf);
        Func<Encoding, object, object> getByteCountFunc = MagicMethod<Encoding>(getByteCount);
       
        Console.WriteLine(indexOfFunc(“Hello”, ‘e’));
        Console.WriteLine(getByteCountFunc(Encoding.UTF8, “Euro sign: \u20ac”));
    }
   
    static Func<T, object, object> MagicMethod<T>(MethodInfo method)
    {
        // TODO: Implement this method!
        throw new NotImplementedException();
    }
}

Note: I was going to demonstrate this by calling DateTime.AddDays, but for value type instance methods the implicit first first parameter is passed by reference, so we’d need a delegate type with a signature of DateTime Foo(ref DateTime original, double days) to call CreateDelegate. It’s feasible, but a bit of a faff. In particular, you can’t use Func<...> as that doesn’t have any by-reference parameters.

Make sure you understand what we’re aiming for here. Notice that we’re not really type-safe – just like we wouldn’t be if we were calling MethodInfo.Invoke. Of course we’d normally want type safety, but in this case it would make the calling code much more complicated, and in some places it might effectively be impossible. So, with the goal in place, we know we need to implement MagicMethod. (It’s not called MagicMethod in the real source code, of course – but frankly it’s quite a tricky method to name sensibly, and at this stage it really does feel like magic.)

The first obvious attempt at implementing MagicMethod would be to use CreateDelegate as we’ve done before, like this:

// Warning: doesn’t actually work!
static Func<T, object, object> MagicMethod<T>(MethodInfo method)
{
    return (Func<T, object, object>) Delegate.CreateDelegate
        (typeof(Func<T, object, object>), method);
}

Unfortunately, that fails – the call to CreateDelegate fails with an ArgumentException because the delegate type isn’t right for the method that we’re trying to call. The delegate types don’t have to be exactly right, just compatible (as of .NET 2.0) – but we need an explicit conversion from object to the right parameter type, and a potentially boxing conversion of the return value. We still want to call CreateDelegate though… so somewhere we’re going to have to create a Func<TTarget, TParam, TReturn> where TTarget is a type parameter representing the type of object we’re going to call the method on, TParam is the type of the single parameter the method accepts, and TReturn is the return type of the method.

We could do that directly with reflection, using typeof(Func<,,>) to get the open type (not to be confused with an open delegate!), then calling Type.MakeGenericType to create the right constructed type. We’ll need to do something like that anyway, but it’s actually easier to write another generic method with the right type parameters for this part. That will let us convert the MethodInfo into a delegate, but then what are we going to do with it? How can we convert a Func<TTarget, TParam, TReturn> into a Func<TTarget, object, object>? Well, we need to cast the parameter from object to TParam, and then convert the result from TReturn to object, which may involve boxing. If we were writing a method to do this, it would look something like this:

static object CallAndConvert<TTarget, TParam, TReturn>
    (Func<TTarget, TParam, TReturn> func, TTarget target, object param)
{
    // Conversion from TReturn to object is implicit
    return func(target, (TParam) param);
}

We don’t want to execute that code at the moment – we want to create a delegate which will execute it later. The easiest way to do that is to move the code into a lambda expression within a normal method which already has a reference to the Func<TTarget, TParam, TResult>. That lambda expression will then be converted into a delegate of the type we really want. It may feel like we’re just adding layer upon layer of indirection (and indeed we are) but we’re genuinely making progress. Honest. Here’s the new generic method:

static Func<TTarget, object, object> MagicMethodHelper<TTarget, TParam, TReturn>(MethodInfo method)
{
    // Convert the slow MethodInfo into a fast, strongly typed, open delegate
    Func<TTarget, TParam, TReturn> func = (Func<TTarget, TParam, TReturn>)Delegate.CreateDelegate
        (typeof(Func<TTarget, TParam, TReturn>), method);
       
    // Now create a more weakly typed delegate which will call the strongly typed one
    Func<TTarget, object, object> ret = (TTarget target, object param) => func(target, (TParam) param);
    return ret;
}

(We could return the lambda expression directly – the ret variable is only present as an attempt to add some clarity. Likewise the )

We’re now just one step away from having a working program – we need to implement MagicMethod by calling MagicMethodHelper. There’s one obvious problem though – we need three type arguments to call MagicMethodHelper, and we’ve only got one of them in MagicMethod. We know the other two at execution time, based on the parameter type and return type of the MethodInfo we’ve been passed. The fact that we only know them at execution time suggests the next step – we need to use reflection to invoke MagicMethodHelper. We need to fetch the generic method and then supply the type arguments. It’s easier to show this than to describe it:

static Func<T, object, object> MagicMethod<T>(MethodInfo method) where T : class
{
    // First fetch the generic form
    MethodInfo genericHelper = typeof(Test).GetMethod(“MagicMethodHelper”,
        BindingFlags.Static | BindingFlags.NonPublic);
       
    // Now supply the type arguments
    MethodInfo constructedHelper = genericHelper.MakeGenericMethod
        (typeof(T), method.GetParameters()[0].ParameterType, method.ReturnType);
           
    // Now call it. The null argument is because it’s a static method.
    object ret = constructedHelper.Invoke(null, new object[] {method});
       
    // Cast the result to the right kind of delegate and return it
    return (Func<T, object, object>) ret;
}    

I’ve added the where T : class constraint to make sure (at compile-time) that we don’t run into the problem I mentioned earlier around calling value type methods. It may seem slightly odd that we’re using reflection to call MagicMethodHelper when the whole point of the exercise was to avoid invoking methods by reflection – but we only need to invoke the method once, and we can use the returned delegate many times. Here’s the complete program, ready to compile and run:

using System;
using System.Reflection;
using System.Text;

public class Test
{
    static void Main()
    {
        MethodInfo indexOf = typeof(string).GetMethod(“IndexOf”, new Type[]{typeof(char)});
        MethodInfo getByteCount = typeof(Encoding).GetMethod(“GetByteCount”, new Type[]{typeof(string)});
       
        Func<string, object, object> indexOfFunc = MagicMethod<string>(indexOf);
        Func<Encoding, object, object> getByteCountFunc = MagicMethod<Encoding>(getByteCount);
       
        Console.WriteLine(indexOfFunc(“Hello”, ‘e’));
        Console.WriteLine(getByteCountFunc(Encoding.UTF8, “Euro sign: \u20ac”));
    }
   
    static Func<T, object, object> MagicMethod<T>(MethodInfo method) where T : class
    {
        // First fetch the generic form
        MethodInfo genericHelper = typeof(Test).GetMethod(“MagicMethodHelper”,
            BindingFlags.Static | BindingFlags.NonPublic);
       
        // Now supply the type arguments
        MethodInfo constructedHelper = genericHelper.MakeGenericMethod
            (typeof(T), method.GetParameters()[0].ParameterType, method.ReturnType);
           
        // Now call it. The null argument is because it’s a static method.
        object ret = constructedHelper.Invoke(null, new object[] {method});
       
        // Cast the result to the right kind of delegate and return it
        return (Func<T, object, object>) ret;
    }   
       
    static Func<TTarget, object, object> MagicMethodHelper<TTarget, TParam, TReturn>(MethodInfo method)
        where TTarget : class
    {
        // Convert the slow MethodInfo into a fast, strongly typed, open delegate
        Func<TTarget, TParam, TReturn> func = (Func<TTarget, TParam, TReturn>)Delegate.CreateDelegate
            (typeof(Func<TTarget, TParam, TReturn>), method);
       
        // Now create a more weakly typed delegate which will call the strongly typed one
        Func<TTarget, object, object> ret = (TTarget target, object param) => func(target, (TParam) param);
        return ret;
    }
}

Conclusion

This isn’t the kind of thing which I enjoy having in production code. It’s frightfully complicated – we’re finding a method via reflection, invoking a different (and generic) method via reflection in order to turn the first method into a delegate and then return a different delegate which calls it. While I don’t like having “clever” code like this in production, I take immense pleasure from getting it to work in the first place. This is one of the rare occasions where the result makes all the cleverness worth it, too – combined with the other optimisations, my Protocol Buffers port is now much, much faster – the reflection invocations are no longer a bottleneck. (We lose a little bit of efficiency by having one delegate call another, but it’s still massively quicker than using reflection.)

Regardless of the complexity involved later on, the simpler parts of this post (calling Delegate.CreateDelegate where you already know the signature, and the possibility of creating open delegates) are likely to be more widely applicable. By using a delegate instead of MethodInfo, not only are there significant performance improvements, but also a strongly typed way of calling the method. From now on, I’ll certainly be considering whether or not it might be worth using a delegate any time I use reflection.

Making the most of generic type inference

Introduction


Specifying type arguments for generic types and methods can be a pain, especially when there are multiple type parameters involved. For instance, imagine having to explicitly specify TOuter, TInner, TKey and TResult for a call to Enumerable.Join! Fortunately the compiler can work out the type arguments most of the time – but only for generic methods. It doesn’t do anything for generic types. However, all is not lost…


Overloading type names by number of type parameters


One feature of C# and .NET which isn’t used terribly often (in my experience) is the ability to use the same type name for different types – so long as they have different numbers of type parameters. This is how System.Nullable and System.Nullable<T> coexist, for example. Like all language features this is open to massive abuse if you have several types with very different semantic meanings, but when applied with discretion it can be very helpful.


We can use this to our advantage when we want to call a constructor or static method of a generic type without specifying the type parameters. The basic idea is that you create a nongeneric type (or just one with fewer type parameters) and then put a generic method in that class. The generic method in the nongeneric class then calls a member in the generic class, using the method’s type parameters as the type arguments for the generic class. (Try getting all of that right after a few drinks!) Now that you’ve got a generic method, you can use type inference to avoid having to explicitly state the type arguments. Fortunately it’s a lot simpler than it sounds…


To show you what I mean, let’s look at a bit of code from my MiscUtil library. (This code isn’t in the latest release drop, but will be in the next one – and this post provides all the important code anyway.)


Projection comparisons


I’ve found the OrderBy method in LINQ very useful, and I wanted to be able to use the same “compare using a projection” idea elsewhere. The IComparer<T> interface is used in various places in the .NET API (List<T>.Sort being an obvious example) but implementing it can be a bit tedious – even though it’s a single method. So, let’s build a ProjectionComparer type which knows how to compare two objects by applying the same projection to both of them, and then using another comparer to compare the results.


There are two types involved – the source of the projection, and the key we’re projecting it to. This naturally suggests a type with two type parameters, TSource and TKey. For instance, when projecting from a Person type to their name, we might have TSource=Person and TKey=string.


The most obvious piece of information we need to create a projection comparer is the projection itself. A delegate is the obvious way of representing this – a Func<TSource, TTarget> which can be applied to each item we try to compare. We then need to know how to compare the names (e.g. case-insensitive, ordinal etc) – functionality which is provided by StringComparer in this example, and IComparer<TKey> in general. The Comparer<T>.Default property comes in handy to let us get away without specifying a comparer in many situations.


With those few design decisions, we can implement ProjectionComparer<TSource, TKey> pretty simply:


 


public class ProjectionComparer<TSource, TKey> : IComparer<TSource>
{
    private readonly Func<TSource, TKey> projection;
    private readonly IComparer<TKey> comparer;

    public ProjectionComparer(Func<TSource, TKey> projection)
        : this (projection, null)
    {
    }
       
    public ProjectionComparer(Func<TSource, TKey> projection, IComparer<TKey> comparer)
    {
        if (projection==null)
        {
            throw new ArgumentNullException(“projection”);
        }
        this.comparer = comparer ?? Comparer<TKey>.Default;
        this.projection = projection;
    }

    public int Compare(TSource x, TSource y)
    {
        // Don’t want to project from nullity
        if (x==null && y==null)
        {
            return 0;
        }
        if (x==null)
        {
            return -1;
        }
        if (y==null)
        {
            return 1;
        }
        return comparer.Compare(projection(x), projection(y));
    }
}

 


That’s functionally complete, but it’s a bit of a pain to create instances of it. Our previous example would require something like this:


 


var nameComparer = new ProjectionComparer<Person, string>(person => person.Name);

 


It’s not bad, but we can do better.


Introducing the nongeneric ProjectionComparer type


The next step is almost as simple as imagining how we want to create instances. We don’t have to use a nongeneric type with the same name as the generic type, but it keeps things consistent, and forms a simple pattern to follow at other times. So, let’s imagine being able to write this:


 


var nameComparer = ProjectionComparer.Create(person => person.Name);

 


Unfortunately we can’t quite achieve that. There’s no way for the compiler to know the type of the parameter in the lambda expression. However, we have three options we can use:


 


// Explicitly type the lambda expression’s parameter
var option1 = ProjectionComparer.Create((Person person) => person.Name);

// Pass in a dummy parameter of the right type
var option2 = ProjectionComparer.Create(dummyPerson, person => person.Name);

// Use a class with one generic type parameter, and infer the other
var option3 = ProjectionComparer<Person>.Create(person => person.Name);

 


Each of these options is just a way of telling the compiler what TSource should be. The first two are implemented in a totally nongeneric class. The third is implemented in a generic class with a type parameter for TSource but letting the compiler infer TKey. Note that we have to make this split because you can’t explicitly specify some type arguments and let the compiler infer the others. The actual code for these methods is very straightforward indeed. I haven’t included overloads where the comparer is explicitly specified, but it’s very simple to do so if required.


 


public static class ProjectionComparer
{
    // For option 1
    public static ProjectionComparer<TSource, TKey> Create<TSource, TKey>(Func<TSource, TKey> projection)
    {
        return new ProjectionComparer<TSource, TKey>(projection);
    }

    // For option 2
    public static ProjectionComparer<TSource, TKey> Create<TSource, TKey>(TSource ignored, Func<TSource, TKey> projection)
    {
        return new ProjectionComparer<TSource, TKey>(projection);
    }

}

// For option 3
public static class ProjectionComparer<TSource>
{    
    public static ProjectionComparer<TSource, TKey> Create<TKey>(Func<TSource, TKey> projection)
    {
        return new ProjectionComparer<TSource, TKey>(projection);
    }
}

 


Conclusion


There’s nothing particularly difficult in this post, but it’s sometimes easy to forget that the C# compiler can help you out when it comes to filling in type arguments. Of course it only helps when you already providing enough information to the compiler with normal method parameters, but it’s still a nice little trick to have up your sleeve when you’re trying to make your APIs that bit more pleasant to use.

Book review: Accelerated C# 2008 by Trey Nash

Time for another book review, and this time it’s a due to a recommendation from a reader who has this one, C# in Depth and Head First C#.

Resources

Introduction and disclaimer

My normal book review disclaimer applies, but probably more so than ever before. Yes, Accelerated C# 2008 is a competitor to C# in Depth. They’re different in many ways, but many people would no doubt be in the target audience for both books. If you meet that criterion, please be aware that as the author of C# in Depth I can’t possibly be 100% objective when reviewing another C# book. That said, I’ll try to justify my opinions everywhere I can.

Target audience and content overview

Accelerated C# 2008 is designed to appeal to existing developers with experience in an OO language. As one of the Amazon reviews notes, you may struggle somewhat if you don’t have any .NET experience beforehand – while it should be possible to read it knowing only Java or C++, there are various times where a certain base level of knowledge is assumed and you’ll want to refer to MSDN for some background material. If you come at the book with no OO experience at all, I expect you’ll have a hard time. Chapter 4 does cover the basics of OO in .NET (classes, structs, methods, properties etc) this isn’t really a beginner’s book.

In terms of actual content covered, Accelerated C# 2008 falls somewhere between C# in Depth (almost purely language) and C# 3.0 in a Nutshell (language and then core libraries). It doesn’t attempt to cover all the core technologies (IO, reflection, security, interop etc are absent) but it goes into detail beyond the C# language when it comes to strings, exceptions, collections, threading and more. As well as purely factual information, there’s a lot of guidance as well, including a whole chapter entitled “In Search of C# Canonical Forms.”

General impressions

I’d like to make it clear to start with that I like the book. I have a number of criticisms, none of which I’m making up for the sake of being critical – but that in no way means it’s a bad book at all. It’s very unlikely that you know everything in here (I certainly didn’t) and the majority of the guidance is sound. The code examples are almost always self-contained (a big plus in my view) and Trey’s style is very readable. Where there are inaccuracies, they’re usually pretty harmless, and the large amount of accurate and insightful material makes up for them.

Just as I often compare Java to C# in my book, so Trey often compares C++ to C# in his. While my balance of C# to C++ knowledge is such that these comments aren’t particularly useful to me, I can see them being good for a newcomer to C# from a C++ background. I thought there might have been a few too many comparisons (I understood the point about STL and lambdas/LINQ the first time round…) but that’s just a minor niggle.

Where C# in Depth is primarily a “read from start to finish” book and C# 3.0 in a Nutshell is primarily a reference book (both can be used the other way, of course) Accelerated C# 2008 falls between the two. It actually achieves the best of both worlds to a large extent, which is an impressive feat. The ordering could be improved (more on this later on) but the general feeling is very good.

One quick word about the size of the book in terms of content: if you’re one of those people who judges the amount of useful content in a book on its page count, it’s worth noting that the font in this book is pretty small. I would guess that it packs about 25% more text per page than C# in Depth does, taking its “effective” page count from around 500 to 625. Also, the content is certainly meaty – you’re unlikely to find yourself skimming over loads of simple stuff trying to get to the good bits. Speaking of “getting to the good bits” let’s tackle my first significant gripe.

Material organisation

If you look at the tables of contents for Accelerated C# 2008 and Accelerated C# 2005, you’ll notice that the exact same chapter titles in the 2005 edition carry over in the same order in the 2008 edition. There are three extra chapters in the new edition, covering extension methods, lambda expressions and LINQ. That’s not to say that the content of the “duplicate” chapters is the same as before – C# 3.0 features are introduced in the appropriate place within existing chapters. In terms of ordering the chapters, I think it would be have been much more appropriate to keep the last chapter of the old edition – “In Search of C# Canonical Forms” – as the last chapter of the new edition. Apart from anything else, that would allow it to include hints and tips involving the new C# 3 features which are currently covered later. It really feels like a “wrapping up” chapter, and deserves to be last.

That’s not the only time that the ordering felt strange, however. Advanced topics (at least ones which feel advanced to me) are mixed in with fairly basic ones. For instance, in the chapter on exceptions, there’s a section about “exception neutrality” which includes details about constrained execution regions and critical finalizers. All interesting stuff – even though I wish there were more of a prominent warning saying, “This is costly to both performance and readability: only go to these lengths when you really, really need to.” However, this comes before a section about using try/finally blocks and the using statement to make sure that resources are cleaned up however a block is exited. I can’t imagine anyone who knows enough C# to take in the exception neutrality material also not knowing about try/finally or the using statement (or how to create your own custom exception class, which comes between these two topics).

Likewise the chapter which deals with collections, including generic ones, comes before the chapter on generics. If I were a reader who didn’t know generics already, I think I’d get very confused reading about ICollection<T> without knowing what the T meant. Now don’t get me wrong: ordering material so that you don’t get “circular references” is often hard if not impossible. I just think it could have been done better here.

Aiming too deep?

It’s not like me to criticise a book for being too deep, but I’m going to make an exception here. Every so often, I came away from a topic thinking that it would have been better covered a little bit more lightly. Sometimes this was because a running example became laborious and moved a long way from anything you were actually likely to want to do in real life. The sections on “borrowing from functional programming” and memoization/currying/anonymous recursion felt guilty of this. It’s not that they’re not interesting topics, but the examples picked didn’t quite work for me.

The other problem with going deep is that you really, really need to get things right – because your readers are less likely to spot the mistakes. I’ll give three examples here:

  • Trey works hard on a number of occasions to avoid boxing, and points it out each time. Without any experience in performance tuning, you’d be forgiven for thinking that boxing is the primary cause of poor performance in .NET applications based on this book. While I agree that it’s something to be avoided where it’s possible to do so without bending the design out of shape, it doesn’t deserve to be laboured as much as it is here. In particular, Trey gives an example of a complex number struct and how he’s written appropriate overloads etc to avoid boxing. Unfortunately, to calculate the magnitude of the complex number (used to implement IComparable in a manner which violates the contract, but that’s another matter) he uses Math.Pow(real, 2) + Math.Pow(img, 2). Using a quick and dirty benchmark, I found that using real * real + img * img instead of Math.Pow made far, far more difference than whether or not the struct was boxed. (I happen to think it’s more readable code too, but never mind.) There was nothing wrong with avoiding the boxing, but in chasing the small performance gains, the big ones were missed.

  • In the chapter on threading, there are some demonstrations of lock-free programming (before describing locking, somewhat oddly – and without describing the volatile modifier). Now, personally I’d want to discourage people from attempting lock-free programming at all unless they’ve got a really good reason (with evidence!) to support that decision – but if you’re going to do it at all, you need to be hugely careful. One of the examples basically has a load of threads starting and stopping, updating a counter (correctly) using Interlocked.Increment/Decrement. Another thread monitors the count and periodically reports it – but unfortunately it uses this statement to do it:

    threadCount = Interlocked.Exchange(ref numberThreads, numberThreads);

    The explanation states: “Since the Interlocked class doesn’t provide a method to simply read an Int32 value in an atomic operation, all I’m doing is swapping the numberThreads variable’s value with its own value, and, as a side effect, the Interlocked.Exchange method returns to me the value that was in the slot.” Well, not quite. It’s actually swapping the numberThreads variable’s value with a value evaluated at some point before the method call. If you rewrite the code like this, it becomes more obviously wrong:

    int tmp = numberThreads;
    Thread.Sleep(1000); // What could possibly happen during this time, I wonder?
    threadCount = Interlocked.Exchange(ref numberThreads, tmp);

    The call to Thread.Sleep is there to make it clear that numberThreads can very easily change between the initial read and the call to Interlocked.Exchange. The correct fix to the code is to use something like this:

    threadCount = Interlocked.CompareExchange(ref numberThreads, 0, 0);

    That sets numberThreads atomically to the value 0 if (and only if) its value is already 0 – in other words, it will never actually change the value, just report it. Now, I’ve laboured the explanation of why the code is wrong because it’s fairly subtle. Obvious errors in books are relatively harmless – subtle ones are much more worrying.

  • As a final example for this section, let’s look at iterator blocks. Did you know that any parameters passed to methods implemented using iterator blocks become public fields in the generated class? I certainly didn’t. Trey pointed out that this meant they could easily be changed with reflection, and that could be dangerous. (After looking with reflector, it appears that local variables within the iterator block are also turned into public fields.) Now, leaving aside the fact that this is hugely unlikely to actually bite anyone (I’d be frankly amazed to see it as a problem in the wild) the suggested fix is very odd.

    The example Trey gives is where originally a Boolean parameter is passed into the method, and used in two places. Oh no! The value of the field can be changed between those two uses, which could lead to problems! True. The supposed fix is to wrap the Boolean value in an immutable struct ImmutableBool, and pass that in instead. Now, why would that be any better? Certainly you can’t change the value within the struct – but you can easily change the field‘s value to be a completely different instance of ImmutableBool. Indeed, the breakage would involve exactly the same code, just changing the type of the value. The other train of thought which suggests that this approach would fail is that bool is already immutable, so it can’t be the mutability of the type of the field that causes problems. I’m sure there are much more useful things that Trey could have said in the two and a half pages he spent describing a broken fix to an unimportant problem.

Sorry, that was getting ranty for a bit… but I hope you understand why. Before concluding this review, let’s look at one chapter which is somewhat different to the rest, and which I’ve mentioned before:

In Search of C# Canonical Forms (aka “Design and Implementation Guidelines” :)

I’d been looking forward to this part of the book. I’m always interested in seeing what other people think the most important aspects of class design are. The book doesn’t go into much detail about abstract orientation (in this chapter, anyway – there’s plenty scattered through the book) but concentrates on core interfaces you might implement, etc. That’s fine. I’m still waiting for a C# book to be written to truly be on a par with Effective Java (I have the second edition waiting to be read at work…) but I wasn’t expecting it all to be here. So, was this chapter worth the wait?

Somewhat. I was very glad to see that the first point around reference types was “Default to sealed classes” – I couldn’t agree more, and the arguments were well articulated. Many other guidelines were either entirely reasonable or at least I could go either way on. There were a few where I either disagreed or at least would have put things differently:

  • Implementing cloning with copy constructors: one point about cloning which wasn’t mentioned is that (to quote MSDN) “The resulting clone must be of the same type as or a compatible type to the original instance.” The suggested implementation of Clone in the book is to use copy constructors. This means that every subclass must override Clone to call its own copy constructor, otherwise the instance returned will be of the wrong type. MemberwiseClone always creates an instance of the same type. Yes, it means the constructor isn’t called – but frankly the example given (performing a database lookup in the constructor) is a pretty dodgy cloning scenario in the first place, in my view. If I create a clone and it doesn’t contain the same data as the original, there’s something wrong. Having said that, the caveats Trey gives around MemberwiseClone are all valid in and of themselves – we just disagree about their importance. The advice to not actually implement ICloneable in the first place is also present (and well explained).
  • Implementing IDisposable: Okay, so this is a tough topic, but I was slightly disappointed to see the recommendation that “it’s wise for any objects that implement the IDisposable interface to also implement a finalizer […]” Now admittedly on the same page there’s the statement that “In reality, it’s rare that you’ll ever need to write a finalizer” but the contradiction isn’t adequately resolved. A lot of people have trouble understanding this topic, so it would have been nice to see really crisp advice here. My 20 second version of it is: “Only implement a finalizer if you’re holding on to resources which won’t be cleaned up by their own finalizers.” That actually cuts out almost everything, unless you’ve got an IntPtr to a native handle (in which case, use SafeHandle instead).
    • As a side note, Trey repeatedly claims that “finalizers aren’t destructors” which irks me somewhat as the C# spec (the MS version, anyway) uses the word “destructor” exclusively – a destructor is the way you implement a .NET finalizer in C#. It would be fine to say “destructors in C# aren’t deterministic, unlike destructors in C++” but I think it’s worth acknowledging that the word has a valid meaning in the context of C#. Anyway…
  • Implementing equality comparisons: while this was largely okay, I was disappointed to see that there wasn’t much discussion of inheritance and how it breaks equality comparisons in a hard-to-fix way. There’s some mention of inheritance, but it doesn’t tackle the issue I think is thorniest: If I’m asking one square whether it’s equal to another square, is it enough to just check for everything I know about squares (e.g. size and position)? What about if one of the squares is actually a coloured square – it has more information than a “basic” square. It’s very easy to end up with implementations which break reflexivity, simply because the question isn’t well-defined. You effectively need to be asking “are these two objects equal in <this> particular aspect” – but you don’t get to specify the aspect. This is an example where I remember Effective Java (first edition) giving a really thorough explanation of the pitfalls and potential implementations. The coverage in Accelerated C# 2008 is far from bad – it just doesn’t meet the gold standard. Arguably it’s unfair to ask another book to compete at that level, when it’s trying to do so much else as well.
  • Ordering: I mentioned earlier on that the complex number class used for a boxing example failed to implement comparisons appropriately. Unfortunately it’s used as the example specifically for “how to implement IComparable and IComparable<T>” as well. To avoid going into too much detail, if you have two instances x and y such that x != y but x.Magnitude == y.Magnitude, you’ll find x.CompareTo(y) == y.CompareTo(x) (but with a non-zero result in both cases). What’s needed here is a completely different example – one with a more obvious ordering.
  • Value types and immutability: Okay, so the last bullet on the value types checklist is “Should this struct be immutable? […] Values are excellent candidates to be immutable types” but this comes after “Need to boxed instances of value? Implement an interface to do so […]” No! Just say no to mutable value types to start with! Mutable value types are bad, bad, bad, and should be avoided like the plague. There are a very few situations where it may be appropriate, but to my mind any advice checklist for implementing structs should make two basic points:
    • Are you sure you really wanted a struct in the first place? (They’re rarely the right choice.)
    • Please make it immutable! Pretty please with a cherry on top? Every time a struct is mutated, a cute kitten dies. Do you really want to be responsible for that?

Conclusion

At the risk – nay, certainty – of repeating myself, I’m going to say that I like the book despite the (sometimes subjective) flaws pointed out above. As Shakespeare wrote in Julius Caesar, “The evil men do lives after them. The good is oft interred with their bones.” So it is with book reviews – it’s a lot easier to give specific examples of problems than it is to report successes – but the book does succeed, for the most part. Perhaps the root of almost all my reservations is that it tries to do too much – I’m not sure whether it’s possible to go into that much detail and cater for those with little or no previous C# experience (even with Java/C++) and keep to a relatively slim volume. It was a very lofty goal, and Trey has done very well to accomplish what he has. I would be interested to read a book by him (and hey, potentially even collaborate on it) which is solely on well-designed classes and libraries.

In short, I recommend Accelerated C# 2008, with a few reservations. Hopefully you can judge for yourself whether my reservations would bother you or not. I think overall I slightly prefer C# 3.0 in a Nutshell, but the two books are fairly different.

Reaction

I sent this to Trey before publishing it, as is my custom. He responded to all my points extremely graciously. I’m not sure yet whether I can post the responses themselves – stay tuned for the possibility, at least. My one problem with reviewing books is that I end up in contact with so many other authors who I’d like to work with some day, and that number has just increased again…