Wilsonhut

Deal with it or don't

Be afraid of params object[]… just in time for Halloween

Paste this into Linqpad:

public enum Dukes

{

Bo,

Luke,

Daisy,

UncleJesse

}

 

// Cb a specific Duke

public void CbTheDukes(Dukes duke, params object[] things)

{

foreach (var thing in things)

{

thing.Dump(duke.ToString());

}

}

 

// Cb all the Dukes

public void CbTheDukes(params object[] things)

{

foreach (var thing in things)

{

thing.Dump(“ALL”);

}

}

 

private void Main()

{

CbTheDukes(“Shepherd to Lost Sheep”, “Got your ears on?”);

}

So… Here’s what we have.

We have a ridiculous enum, a method with an overload, and the main witch, which calls the method.

Running that in linqpad (Language: C# Program) And what do you expect? I expect (and get) the following in the output window:

ALL
Shepherd to Lost Sheep
ALL
Got your ears on?

Also, with this:

CbTheDukes(Dukes.Luke, “You’re the smart one.”);

…you get this:

Luke
You’re the smart one.

…all pretty standard use of overloads.

Since I used an object[], I can contact a Duke with anything:

CbTheDukes(“breaker”, 1, 9);

…and get this, of course:

ALL
breaker
ALL
1
ALL
9

The problem with the params object[] is when you pass a const 0 (zero) in for the first parameter.

CbTheDukes(0, “Do you copy?”);

I expected to get :

ALL
0
ALL
Do you copy?

… but alas, I get this:

Bo
Do you copy?

“Ok”, I thought, “Somehow the .NETs are finding the overload with the enum, because zero will easily cast to the enum.” Then I also thought that passing a const 1 would send a CB message to Luke, but it doesn’t.

CbTheDukes(1, “Do you copy?”);

…actually yields:

ALL
1
ALL
Do you copy?

Only the zero freaks out.

This is only true for a const value. Declare a variable, set it to zero, and pass it in and you get the overload without the enum.

I found this out when using Moq (http://code.google.com/p/moq/). The constructor for Mock<T> has one overload that takes an enum (MockBehavior) and a params object[], and another that takes only a params object[]. Mock an object with a constructor that has an int as the first param and pass the const 0 (zero) in to that bad boy, and you get get an exception – something about ‘Could not find a constructor that would match given arguments’… (unless you have another constructor that is exactly the same, except without the first int parameter, then you might never know! YIKE!)

(I’ve also run into a similar problem when a method has many overloads and one of them takes an object, like the Html helper methods in ASP.NET MVC…)

The lesson is, if you have a method that has a ‘params object[]’ argument… don’t have overloads! …or just don’t, period.

BOO!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: