It's Been Possible, But a Bit Clunky

Eilon has a great post about passing anonymous types as dictionaries, something I abused heavily when working up the HTML Helpers prototype a few years back. I really liked the way you could set attributes using them:

Html.TextBox("name", "value", new {size = 20})

I also know that this isn't what the construct was meant for. It doesn't "feel" right - and many people question (still) the practice of "loosely" sending arguments off to a method.

Flexibility Is OK

One thing that sucks about a static language is that it makes you be precise, all the time. I'm a lazy slob - which is another way of saying that I'm a programmer. If I wanted to be precise I would have been an accountant and stole people's money :).

A particular way that you feel this pain is when you're testing and you all of a sudden realize that - oh noes! - you need to send in an extra bit of information to a method. Crap. You just broke your method signature and slowed your testing down. Testing becomes a drag, and you begin to reason your way out of it, staring at the clock...

An easier way to go about this is to embrace something that Ruby has been doing for a long time: named parameters (that's a generalized term). You'll often see something like this when working in Rails:

my_method :thing1 => "value", :thing2 = Time.now

The method itself looks like this:

def mymethod(args) thingone = args["thing1"] thing_two = args["thing2"] end

In this method, "args" is a hash (like a C# dictionary). Because Ruby uses Duck Typing (it is a typed language - it just does the typing on the fly) - you're able to store whatever value you want inside the hash. If you change your mind later on and decide that you also want to pass "thing3" - awesome! Your method signature doesn't break and you're able to refactor a lot faster.

I Knew I'd Find a Use For the Dynamic Keyword

I should say here and now that the whole "System.Dynamic" namespace is a mystery to me. The first time I heard of it is reading up on

the ExpandoObject, and I remember thinking that the C# team was smoking crack laced with diesel fuel in a pipe made from pure black tar heroin, somewhere deep in Turkey, surrounded by opium dealers mumbling Gregorian Chants.

If you've ever read the Hyperion series you'll know what I mean about the Time Tombs. It's this place on the planet Hyperion wherein time moves backwards. The whole planet is just fine, in terms of the way time works and all - it's just that in this one place time moves backwards and there's this psycho killing machine called the Shrike that rips people to pieces.

I'm convinced that the C# team works in Building 7, and Building 7 is on the planet Hyperion. And Anders is the Shrike.

So... anyway... In pondering dynamic objects, I thought to myself: "now this would make a lovely little bucket to put my method arguments in!". So I tried it:DoStuff(new { Message = "Hello Monkey" }); static void DoStuff(dynamic args) { Console.WriteLine(args.Message); }

And wouldn't ya know:

The gist of this whole thing is that I can now pretty much do in C# what I can do in Ruby, in terms of having flexible methods. If I wanted to get scary, whimsical, and whacky (all at the same time), I could do something like this:

DoStuff("silly", "little", "monkey", DateTime.Now); static void DoStuff(params dynamic[] args) { Console.WriteLine(args[0]); }

Do you see the issue here? While I can send in an array of freaky types, it loses context - meaning I can't discern which element passed into the dynamic array is which. I could probably test by type - but I think it would be much better to append everything to a single dynamic object.

There are other little lovelies in the System.Dynamic namespace - things like ExpandoObject. Unfortunately the compiler does some tricky-tricks at compile time to figure out what it is you're doing. Just like the "var" keyword - ExpandoObject needs to know what it's Expando-ing - even if it's "dynamic". Which is weird. It's more than weird - it's kind of psycho.

Alternative 2: Dictionaries

There are times when you'll need to pass a whole mess of stuff to a method. You could work up a big fatty of a dynamic object - basically treat it like a piece of velcro and "see what sticks" - or you could introduce a modicum of sanity in the process by using a Dictionary.

The one thing you gain here is a bit of clarity in the form of keys. The one thing you lose is that your call gets a bit muddled (Dictionary initializers are super-crunchy). If you know of some sugary syntax to initialize Dictionaries in C# 4 - please leave a comment!

DoStuff(new Dictionary { {"name","silly"}, {"size","little"}, {"thing","monkey"}, {"when",DateTime.Now} }); static void DoStuff(Dictionary args) { Console.WriteLine(args["name"]); }

Why Would I Do This Again?

Keeping your method signatures "nimble" and flexible has been a goal in programming for a long time. In VB6 it was suggested you pass arguments in an array (at least that's what the cert test said to do :). This allows you to change your mind, and your API, with minimal "drag" on your tests.

It also allows you to read the method calls themselves a lot more clearly - there's no need to wonder which of the 4 arguments passed off to a method is the "size" - it says it rather clearly in the call (if not verbosely).

A downside to this is that you lose intellisense - which gives you a code-time description of the arguments required etc. You can, of course, get past that with some good comments explaining precisely what's required. It hasn't bothered the Ruby community - so I can imagine the .NET community can get by as well. Intellisense shouldn't drive design decisions anyway!