DaedTech

Stories about Software

By

Help Yourself To My Handy Extension Methods

There’s nothing like 3 years (or almost 3 years) of elapsed time to change your view on something, such as my take on C# extension methods. At the time I was writing this post, I was surrounded by wanton abuse of the construct, compliments of an Expert Beginner, so my tone there was essentially reminiscent of someone who had just lost a fingertip in a home improvement accident writing a post called “why I don’t like skill saws.” But I’ve since realized that cutting lots of lumber by hand isn’t all it’s cracked up to be. Judicious use of extension methods has definitely aided in the readability of my code.

I’m going to post some examples of ones that I’ve found myself using a lot. I do this almost exclusively in test assemblies, I think because, while code readability is important everywhere, in your unit tests you should literally be explaining to people how your API works using code as prose (my take anyway). So, here are some things I do to further that goal.

ToEnumerable

One of the things that annoyed me for a long time in C# was the thought that initializing lists was clunkier than I want. This isn’t a criticism of the language, per se, as I don’t really know how to make list initialization in the language much more concise. But I wanted it to be on a single line and without all of the scoping noise of curly brackets. I’m picky. I don’t like this line of code:

RetrievalService.Arrange(rs => rs.GetAll()).Returns(new List() { new Foo() });

I’m arranging this retrieval service (using Telerik’s JustMock) so that its GetAll() method returns a list of Foos with just one Foo. The two different instances of Foo are redundant and I don’t like those curly braces. Like I said, picky. Another issue is that a lot of these methods that I’m testing deal in enumerables rather than more defined collection types. And so I wrote this:

public static IEnumerable ToEnumerable(this T target)
{
    return new List() { target };
}

public static IEnumerable ToEnumerable(this T target, int itemCount)
{
    return Enumerable.Repeat(target, itemCount);
}

And writing this method and its overload change the code I don’t like to this:

RetrievalService.Arrange(rs => rs.GetAll()).Returns(new Foo().ToEnumerable());

One occurrence of Foo, zero curly brackets. Way more readable, for my money and, while YMMV, I don’t know if it’s going to vary that much. Is it worth it? Absolutely, in my book. I’ve eliminated duplication and made the test more readable.

IntOrDefault

Do you know what I hate in C#? Safe parsing of various value types from strings. It’s often the case that I want something like “pull an int out of here, but if anything goes wrong, just set it to zero.” And then you know the drill. The declaration of an int. The weird out parameter pattern to Int.TryParse(). The returning of said int. It’s an ugly three lines of code. So I made this:

public static int IntOrDefault(this object target)
{
    int valueToReturn = default(int);
    string parseValue = target != null ? target.ToString() : valueToReturn.ToString();
    int.TryParse(parseValue, out valueToReturn);
    return valueToReturn;
}

Now, if I want to take a whack at a parse, but don’t really care if it fails, I have client code that looks like this:

BlogPostID = reader[IdColumn].IntOrDefault();

What if that indexed value is empty? Zero. What if it has a bunch of non-numeric characters? Zero. What if it is null? Zero. No worries. If there’s actually an int in that string (or whatever it is), then you get the int. Otherwise, 0 (or, technically, default(int)).

I actually created this for a bunch of other primitive types as well, but just showed one here for example’s sake.

GetModel<T>

This is an MVC-specific one for when I’m trying to unit test. I really don’t like that every time I want to unit test a controller method that returns ViewResult I have to get the model as an object and then cast it to whatever I actually want. This syntax is horribly ugly to me:

var view = Target.Edit(id);
var model = (Customer)view.Model;

Now, that may not look like much, but when you start chaining it together and have to add a second set of parentheses like ((Customer)view.Model).SomeCustomerProperty, things get ugly fast. So I did this instead — falling on the ugliness grenade.

public static T GetModel(this ViewResult view)
{
    return ((T)view.Model);
}

It still fails fast with an invalid cast exception, but you don’t need to look at it, and it explains a lot more clearly what you’re doing:

var view = Target.Edit(id);
var model = view.GetModel();

Mocking Function Expression Arguments

This is a little more black belt, but if you’re an architect or senior developer and looking to make unit testing easier on less experienced team members, this may well help you. I have a setup with Entity Framework hidden behind a repository layer, and mocking the repositories gets a little… brutal… for people who haven’t been dealing with lambdas for a long time:

CustomerRepository.Arrange(r => r.Get(Arg.IsAny>>())).Returns(new Customer().ToEnumerable());

“Don’t worry, that just means you can pass it any Expression of Func of Customer to bool!” Now, you’re thinking that, and I’m thinking that, but a lot of people would be thinking, “Take your unit testing and shove it — I don’t know what that is and I’m never going to know.” Wouldn’t it be easier to do this:

CustomerRepository.ArrangeGet().Returns(new Customer().ToEnumerable());

Intent is still clear — just without all of the noise. Well, you can with this extension method:

public static FuncExpectation> ArrangeGet(this IRepository repository) where T: class
{
    return repository.Arrange(r => r.Get(Arg.IsAny>>()));
}

Now, I’ll grant you that this is pretty specific. It’s specific to JustMock and to my implementation of repository methods, but the idea remains. If you’re dealing with Expressions like this, don’t make people trying to write tests type out those nasty argument matcher expressions over and over again. They’re extremely syntactically noisy and add nothing for clarity of purpose.

Edit: Thanks, Daniel and Timothy for the feedback about Chrome. I’ve had intermittent issues with the syntax highlighter plugin over the last few months in Chrome, and the problem stops whenever I change a setting in the syntax highlighter, making me think it’s fixed, but then it comes back. Good news is, seeing it impact others lit a fire under me to go find a replacement, which I did: Crayon Syntax Highlighter. I already like it better, so this is a “make lemonade out of lemons situation.” Thanks again for the feedback and please let me know if you have issues with this new plugin.

9 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Daniel Rose
Daniel Rose
10 years ago

The website says it can’t find the syntax highlighting for C#, so all I see are black code blocks.

Timothy Boyce
Timothy Boyce
10 years ago
Reply to  Daniel Rose

same here.. using Chrome

Thomas
Thomas
10 years ago

What about a varargs method? In Java (and thus surely in C#), you could do:

public static Enumerable toEnumerable(T… items) {
// …
}

RetrievalService.Arrange(rs => rs.GetAll()).Returns(toEnumerable(new Foo()));

Erik Dietrich
10 years ago
Reply to  Thomas

That does exist in the C# world, and you do it with the keyword params. You could certainly write such a method — I’ve just never really had much use for it. In writing tests, I find it very common to have something that returns a collection, but I only care about one of the things in the collection.

Eric Olsson
Eric Olsson
10 years ago

I had a version of ToEnumerable() [mine may have been AsEnumerable()] that I used as well. I just used { yield return whateverObjectYouPassedIn; } as the implementation. I liked the clever use of the iterator block. Now, I’ve moved away from that, and I tolerate some curly braces while taking advantage of the terser array initialization syntax. Something like the following .Returns(new[] { mySingleItem }); One other use of Extension methods that I found as really useful is as a way to only add dependencies when needed. Here’s something more concrete to serve as an example. In my current project,… Read more »

Timothy Boyce
Timothy Boyce
10 years ago
Reply to  Eric Olsson

I was going to mention the implicitly typed array trick.. that is terse enough for me.

Erik Dietrich
10 years ago
Reply to  Eric Olsson

I originally used yield as well, and stopped doing it for some specific reason that I now wish I could remember. I’ve never really used that array initialization syntax — frankly because I don’t find myself using arrays very frequently. Good to know. I can probably tolerate that in a vacuum, though if I’m also using an object initializer, that’s probably too many curly braces for me.

That bit of dependency management strikes me as a good compromise — a way to keep assembly references to a meaning while expressing how you actually want things organized.

Vince
Vince
10 years ago

There’s a method I use for casting which is similar.

// Usage

var intResult = Parse(“1”, 0, int.TryParse); // Returns 1

var dateResult = Parse(“asdf”, DateTime.Now, DateTime.TryParse); // Returns 18/07/2013 1:39:06 PM

delegate TParsedValue ParseFunc(T input, out U output);

static V Parse(T valueToBeParsed, V defaultVal, ParseFunc dele) {

V result;

bool success = dele(valueToBeParsed, out result);

if (success) {

return result;

}

return defaultVal;

}

Erik Dietrich
10 years ago
Reply to  Vince

That’s a clever way to solve the problem that annoyed me about what I wrote which is having to create an extension method for each primitive type.