0

Currently I'm using .Net 3.5 so please let me know if it has been fixed in a later version.

Currently I have 2 methods with the following signatures:

void Method1(string, string)
void Method1(string, params string[])

If I make a call such as this

Method1("test1", "test2")

how does the compiler know which method to call? Why does .Net allow this?

I assume that in the IL, the resulting code is different and therefore allowed, but it shouldn't be, because you can get unexpected results. Is there a good reason why this is allowed?

Thanks in advance.

CodingMadeEasy
  • 2,257
  • 4
  • 19
  • 31
  • 3
    You don't get unexpected results, the closest match is the first one and that's the one the compiler will pick. – Bobby Tables Oct 06 '15 at 15:10
  • 1
    a string value is different from an array with one string element – Beth Oct 06 '15 at 15:10
  • http://stackoverflow.com/questions/3190248/how-does-c-sharp-choose-with-ambiguity-and-params – M.kazem Akhgary Oct 06 '15 at 15:20
  • It is not ambiguous to the .NET Framework at all, a string never matches a string[]. That you can call it by passing just a string and not a string[] and the C# compiler auto-generates the array is a C# language implementation detail. The C# language specification states the overload resolution rules to resolve ambiguity. – Hans Passant Oct 06 '15 at 15:22
  • Method1("test1","test2") and Method1("test1",new[]{"test2"}) will call both methods – Bgl86 Oct 06 '15 at 15:52

1 Answers1

7

how does the compiler know which method to call?

It follows the overload resolution rules listed in the C# language specification. In particular, in section 7.5.3.2 (looking at the C# 4 spec, but I believe C# 5 has the same numbering here) - "Better Function Member":

In case the parameter type seqquences are equivalent [...] the following tie-breaking ruls are applied, in order, to determine the better function member:

  • ...
  • 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.

So in your example, it's going to call the first overload.

Why does .Net allow this?

Because it can be useful in various cases (e.g. Console.WriteLine for a start).

I assume that in the IL, the resulting code is different and therefore allowed, but it shouldn't be, because you can get unexpected results.

You only get unexpected results if you don't expect the C# compiler to follow its specification. In that case, pretty much any behaviour can be unexpected.

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194