C#: (a few of) The Good Parts

After any prolonged dive into a particular technology stack, I end up with a set of tools and features I feel most comfortable with — the ones that most naturally fit how the rest of the team and I choose to build. Being part of a team at Atomic Object means those tools will be the ones enable us to accomplish more with less code, express our intent clearly, write fewer, better tests, and code that is more easily testable. The following are a few of the bright parts of working with C# in the past year.

h2. Lambdas

A familiar concept to many of us who use Ruby, “Haskell”:https:/how-to-write-a-compiler-in-an-afternoon/, or other languages that encourage functional programming paradigms, lambda functions are available in C# (as of version 3.0). They are proper types — generics, actually (more on those later) — and they can be used in much the same way as lambdas in other languages. Lazy evaluation, currying, and lambda-based filtering are all within easy reach.

To look beyond the typical lambda uses, take a look at LINQ. It uses lambda expressions under the hood. This becomes especially clear when you forego the SQL-like syntax I see in most examples and use the extension methods provided on IEnumerable and IQueryable dirctly. The interesting part is, the lambdas aren’t executed — they’re inspected. This means that I can have intellisense goodness and refactoring support through ReSharper in places where I’d normally be passing around strings that are frequently ignored by those tools. There is a lot of magic going on under the hood with LINQ’s lambda inspection and its behavior may not match your expectations unless you keep this in mind. For example, an implementation of IQueryable will know how to deal with IEnumerable.Any() but probably not your custom extension method.

using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;

namespace GoodParts
{

    class Lambdas
    {
        [Test]
        public void WriteSomeLambdas()
        {
            var things = new[] { "one", "two", "three" };
            Assert.AreEqual("two", things.Where(i => i == "two").First());

            Func<IEnumerable<string>, string> firstOrEmptyString = x => x.FirstOrDefault() ?? "";
            Assert.AreEqual("", firstOrEmptyString(new string[]{}));
            Assert.AreEqual("hello", firstOrEmptyString(new string[]{"hello", "second", "third"}));
        }
    }
}

h2. Generics

Along with lambdas, the generics support in C# helps make it easier to write faster, more cleanly flexible code. The provided List, Dictionary, Tuple, and other generic classes form a solid foundation to build nested data structures we find so easy to construct in Ruby and JavaScript. But, as great as those are, my favorites are IEnumerable and IQueryable.

IEnumerable provides a consistent way to deal with almost any type of homogenous collection. It’s exceptionally convenient to use in defining methods that accept or return groups of objects. As I mentioned previously, LINQ provides a lot of functionality on top of IQueryable and IEnumerable. Filtering, sorting, and projection methods feel natural as methods on these generic collections and we ended up accomplishing a lot through chains of list processing method calls.

Another note of caution with IEnumerable is that they are lazy. Extremly lazy. Laziness is good, to a point, but iterating through an enumerable multiple times will probably execute the build-up of the consituent elements multiple times unless you’re careful to avoid it. The latest versions of ReSharper will warn you of possible multiple enumerations, which is very helpful. We were also bitten a few times by an enumerable not enumerating when expected during test build-up (e.g., using Enumerable.Range and Select to create and return rows in a database doesn’t work well unless you force the enumeration).

using System;
using System.Collections.Generic;
using NUnit.Framework;

namespace GoodParts
{
    [TestFixture]
    public class GenericsTest
    {
        [Test]
        public void Generics_are_good_for_nested_data_structures()
        {
            var data = new Dictionary<string, Tuple<int, int>>
                           {
                               {"something",    new Tuple<int, int>(2,4)},
                               {"another_item", new Tuple<int, int>(6,8)}
                           };
            Assert.AreEqual(2, data["something"].Item1);
        }

        [Test]
        public void You_can_subclass_generic_classes()
        {
            var empty = new ComplexType();
            var data = new ComplexType()
                           {
                               {"something", new Tuple<int, int>(2,242)}
                           };
            data.SpecialProperty = "avoid conflicts with dictionary keys";
            Assert.AreEqual(0, empty.Count);
            Assert.AreEqual(2, data["something"].Item1);
        }
    }

    public class ComplexType : Dictionary<string, Tuple<int,int>>
    {
        public string SpecialProperty { get; set; }
    }
}

h2. Extension Methods

We also appreciated the ability to create extension methods on existing objects. While they have their limits (can be difficult to mock, have to be static) we found they were useful for expressing intent clearly when dealing with IEnumerables and reducing the need for conditional statements. For example, we created an extension method FirstOr404() on IEnumerable that does exactly what it sounds like — either returns the first element in the set or throws a 404 exception with a reasonable message if there was nothing present.

LINQ uses extension methods extensively, which is why you may not notice all the wonderful methods on IEnumerable until you include System.Linq in your C# file.

using System.Linq;

public static class EnumerableUtils {

    // First item, or throw 404 exception
    public static TSource FirstOr404<TSource>(this IEnumerable<TSource> source)
    {
        try
        {
            return source.First();
        }
        catch (InvalidOperationException e)
        {
            throw new HttpException(404, "Not Found");
        }
    }
}

h2. Tools

A few of the other libraries and tools we found especially useful during .NET development are listed below in no particular order (except for ReSharper and VsVim — they are first for a reason).

* ReSharper — Invaluable for its refactoring capabilities and added keyboard shortcuts. The NUnit test runner and provided code-simplifying hints were also nice to have.
* VsVim — Not perfect, but it keeps getting better. Many people at Atomic Object spend a LOT of time getting to know Vim and being without it for any length of time leaves me feeling naked and slow. The addition of block selection (ctrl+q) recently was a nice surprise, but I’d use it even if its only feature was h-j-k-l navigation.
* Moq — Uses lambdas for setup and can mock concrete types provided that the methods you’re mocking are virtual. It worked very well, but I would probably have been happy with Rhino Mocks, too.
* SpecFlow — Cucumber for .NET. Used with NUnit and Watin to write system tests driving IE. This worked better than expected, though we wished that declaring a matcher as Given meant we could also use it as a When like we’re used to in th Ruby implementation.
* Structure Map — A simple dependency injection library w/ auto-resolution of unambiguous concrete classes. Dependency injection is great, but not having to write interfaces or verbose configuration make it so much sweeter.