4

I have multiple overloaded methods. But I cannot call the right one. How to tell the compiler that I want especially "THIS METHOD" to be called "WITH THIS PARAMETERS"?

The naughty method is the second one:

public string Translate(string text, params object[] args)
{
    // Blah blah blah...
}

public string Translate(string text, string category, params object[] args)
{
    // Here we do some blah blah blah again...
}

Here when I try to call the first method like this: Translate("Hello {0} {1}", "Foo", "Bar"); the compiler assumes that I'm calling the second method and sets the arguments as category = "Foo" and args = "Bar".

I tried to name the parameters while calling them but it gave me some compiler errors.

Translate("Hello {0} {1}", args: "Foo", "Bar"); // CS1738
Translate("Hello {0} {1}", args: "Foo", args: "Bar"); // CS1740

How can I achieve this?

Yves
  • 3,752
  • 4
  • 29
  • 43
  • "Foo" is a string and that is an exact match of your second parameter `category`. Pass an params array and it should be fine. – NoviceProgrammer Mar 26 '14 at 12:37
  • 1
    Yes, it's easy enough to fix but the root problem is the choice of signatures. This is a thorn that will go on stabbing. It's a place where an overload is a bad idea, and a different name is the better way to go. – david.pfx Mar 26 '14 at 12:46
  • Just something to notice: If it is relevant that you MUST call one specific method out of some overloaded versions, maybe you should rethink your overloaded methods. – Markus Safar Mar 26 '14 at 12:47

1 Answers1

8

To make it short: compiler found an exact match so it's preferred (the one with an argument named category) over the more generic one (as Lippert said about this: "closer is always better than farther away"). For a more general discussion see his answer here on SO about overload resolution with null values.

You may pass an array (instead of single values) like:

Translate("Hello {0} {1}", new string[] { "Foo", "Bar" });

This will match first overload because string[] isn't a string (then 2nd overload doesn't apply) and compiler automatically translate an array to params arguments (if types match).

As alternative you may transform second parameter to something that isn't an exact match (then more generic version will be used):

Translate("Hello {0} {1}", (object)"Foo", "Bar");

In general I would avoid this kind of overloads exactly for this reason. It would be much better to use different names for that functions because when arguments type is object things may become not so obvious and such errors may be subtle and you may get wrong results even if compiler doesn't complain.

Community
  • 1
  • 1
Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
  • 2
    I can't believe how I didn't think to use `new string[]` thing... Thanks it worked ;) – Yves Mar 26 '14 at 14:43