I just encountered something with C# today that I hadn't thought of before. I have two methods in my class, one an overload of the other. They are declared like so:
public void RequirePermissions(params string[] permissions)...
public void RequirePermissions(string message, params string[] permissions)...
In my code, I tried to call the first one like so:
RequirePermissions("Permission1", "Permission2");
...expecting it to call the first overload. Well it called the second overload. The only way I can get it to call the first method in this case is to manually pass a string[]
object like so:
RequirePermissions(new string[] { "Permission1", "Permission2" });
Now, this behavior doesn't confuse me because I understand that the compiler can't tell which method I actually wanted to call based on my provided parameters. But was I not careful this could have gone unnoticed in my code. It seems as though Microsoft should have made the compiler throw an error when it encountered a situation like above. Does anyone have any thoughts on this? Is there another way to call the first overload other than the "solution" I posted?
Agreeing with Adam, I'd change it to something like:
public void RequirePermissions(params string[] permissions)
public void RequirePermissionsWithMessage(string message, params string[] permissions)
Personally, I'd do it this way:
public void RequirePermissions(params string[] permissions)...
public void RequireMessageAndPermissions(string message,
params string[] permissions)...
People fall too in love with overloading sometimes, and when you combine that with a love for the params
keyword, you just increase the confusion level for whomever eventually has to take over your code.
It looks like there is no other way.
You can find explanation to this behaviour in C# spec http://www.jaggersoft.com/csharp_standard /17.5.1.4.htm and here http://www.jaggersoft.com/csharp_standard/14.4.2.1.htm (paragraph 2)
a parameter array is precisely equivalent to a value parameter (§17.5.1.1) of the same type.
and
The expanded form of a method is available only if the normal form of the method is not
applicable and only if a method with the same signature as the expanded form is not already
declared in the same type
Yes, I agree it should probably be a warning when using variable length argument arrays causes an ambiguous overload - it's very much an edge case, and people almost certainly don't mean to create such situations.
I also don't know of any way, other than that you posted, to avoid the call resolution that occurs - other than to avoid doing it in the first place, which I would highly recommend!
You could not use params and be explicit with your signatures.
public void RequirePermissions(string[] permissions)...
public void RequirePermissions(string message, string[] permissions)..