New Fun Blog – Scott Bilas

Take what you want, and leave the rest (just like your salad bar).

Quickie: Fluent Object Casting

without comments

I’m a big fan of fluent interfaces. C# picked this style up in a big way starting with 3.5 and the Enumerable operators class. People are going nuts with it, often for replacing verbose old XML with something a little more readable and compact. Yay. Finally, C# has caught up with languages like Lua or Javascript which have had this ability forever.

Aside from a better configuration language, what I really like about coding fluently is that it’s a steady stream of left-to-right operators, like a pipeline. You think of the next operation and just chain it along, never having to back up. Domain specific sublanguages like LINQ (which I adore, incidentally) can make this even more compact, but I’m talking about the function-based fluent operators.

For enumerables, it’s easy:

[code lang=”csharp”]
var names = list.Where(i => i.Foo > 5).Cast<IBar>().Select(j => j.Name);
[/code]

Take the list, filter it, cast to the type we want, and pull out an element. Operation by operation, left to right. But what about for a single object? That fluency hits a brick wall when you run into C#’s old C-style casting on an individual object.

[code lang=”csharp”]
var name = ((IBar)list.First()).Name;
[/code]

Yuck. Not fluent, and hard to read. As you’re typing, you have to back up, stick the casted type on the front in parens, and, oh yeah, have to also go wrap the whole thing in parens to be able to continue the method chain. I’ve always hated having to do this and in the past would usually pull out the casting into a separate local.

It’s also easy to fix. We just need a little extension method:

[code lang=”csharp”]
public static partial class Extensions
{
[DebuggerStepThrough]
public static T To<T>(this object o)
{ return (T)o; }
}
[/code]

Now it’s nice and fluent:

[code lang=”csharp”]
var name = list.First().To<IBar>().Name;
[/code]

So we now have the system Cast<T> operator for casting elements within an enumerable, and To<T> for casting the overall type. Solid.

May 17th, 2010 at 8:40 pm

Posted in csharp,quickie

Leave a Reply