How does C# choose with ambiguity and params

It's easy to test - the second method gets called.

As to why - the C# language specification has some pretty detailed rules about how ambiguous function declarations get resolved. There are lots of questions on SO surrounding interfaces, inheritance and overloads with some specific examples of why different overloads get called, but to answer this specific instance:

C# Specification - Overload Resolution

7.5.3.2 Better function member

For the purposes of determining the better function member, a stripped-down argument list A is constructed containing just the argument expressions themselves in the order they appear in the original argument list.

Parameter lists for each of the candidate function members are constructed in the following way:

  • The expanded form is used if the function member was applicable only in the expanded form.

  • Optional parameters with no corresponding arguments are removed from the parameter list

  • The parameters are reordered so that they occur at the same position as the corresponding argument in the argument list.

And further on...

In case the parameter type sequences {P1, P2, …, PN} and {Q1, Q2, …, QN} are equivalent > (i.e. each Pi has an identity conversion to the corresponding Qi), the following tie-breaking rules are applied, in order, to determine the better function member.

  • If MP is a non-generic method and MQ is a generic method, then MP is better than MQ.

  • Otherwise, if MP is applicable in its normal form and MQ has a params array and is applicable only in its expanded form, then MP is better than MQ.

  • Otherwise, if MP has more declared parameters than MQ, then MP is better than MQ. This can occur if both methods have params arrays and are applicable only in their expanded forms.

The bolded tie-breaking rule seems to be what is applying in this case. The specification goes into detail about how the params arrays are treated in normal and expanded forms, but ultimately the rule of thumb is that the most specific overload will be called in terms of number and type of parameters.


The second one, the compiler will first try to resolve against explicitly declared parameters before falling back on the params collection.


This overload is tricky...

MyCoolMethod("Hi", "test") obviously calls the 2nd overload, but

MyCoolMethod("Hi"); also calls the 2nd overload. I tested this.

Maybe since both of the inputs are objects, the compiler assume anything passed in will be an array of objects and completely ignores the 1st overload.

It probably has to do with the Better function member resolution mentioned by womp http://msdn.microsoft.com/en-us/library/aa691338(v=VS.71).aspx