9

I have the following methods:

  void Method(string param1, string param2);
  void Method(string param1, object param2);

When I call the method using the following:

  method("string", null);

It gives me an error because the call is ambiguous, the compiler does not know which version to call, because both methods accept null as the second parameter.

How do I overcome this without changing the method name in one of them? the first method will never have null.

MrBoJangles
  • 12,127
  • 17
  • 61
  • 79
Nean Der Thal
  • 3,189
  • 3
  • 22
  • 40
  • Either can certainly have null; but an easy way to call a specific one with null is to make a null variable of the specific type. – Magus Jan 27 '14 at 22:26
  • 1
    Try calling it like: method("string", (string)null); or method("string", (object)null); – Mark Jan 27 '14 at 22:27
  • 1
    Which version of .NET are you use. Because there is no ambiguity. The specification is very clear on overload resolution. – Hamlet Hakobyan Jan 27 '14 at 22:29
  • possible duplicate of [How to resolve ambiguity when argument is null?](http://stackoverflow.com/questions/4044055/how-to-resolve-ambiguity-when-argument-is-null) – Chris Jan 27 '14 at 22:29
  • @HamletHakobyan .Net 4.0 – Nean Der Thal Jan 27 '14 at 22:30
  • No ambiguity is raised. All works fine. – Hamlet Hakobyan Jan 27 '14 at 22:33
  • @HamletHakobyan well, I do not know what language are you using, but in C# and .NET 4.0 it does raise an error indeed. – Nean Der Thal Jan 27 '14 at 22:35
  • 1
    As @HamletHakobyan said, your example should not lead to ambiguity. That is because every `string` is an `object`, but not every `object` is a `string`, so it is not symmetrical, and in that case the "most specific" overload, here `Method(string, string)` is preferred. Your real scenario is probably different. For example if the overloads were `Method(string, string)` and `Method(string, Uri)`, it _would_ be ambiguous. – Jeppe Stig Nielsen Jan 27 '14 at 23:07

2 Answers2

18

The problem is that both string and object are nullable, so null could refer to either overload of the method. You have to cast the null value—as stupid as that sounds—to say explicitely which overload you want to call.

method("string", (string) null);
method("string", (object) null);

This is basically the same as if you defined a variable of either type and passed that then:

string param1 = null;
object param2 = null;

method("string", param1); // will call the string overload
method("string", param2); // will call the object overload

Both param1 and param2 have the same value, null, but the variables are of different types which is why the compiler is able to tell exactly which overload it needs to use. The solution above with the explicit cast is just the same; it annotates a type to the null value which is then used to infer the correct overload—just without having to declare a variable.

poke
  • 369,085
  • 72
  • 557
  • 602
  • Thanks.. is this like a hack? or is it a common way of overcoming this issue? – Nean Der Thal Jan 27 '14 at 22:28
  • No, it’s not a hack. It’s just telling the compiler explicitely which overload you want to call by saying explicitely which version you are referring to. – poke Jan 27 '14 at 22:28
  • This way will at least allow you to avoid R# warnings, as opposed to my preferred way of just using a `string empty = null;` etc. – Magus Jan 27 '14 at 22:28
3

You can be specific about which version of the method you want to call by specifying which type of null you're passing:

Method("string", null as string);
Chris
  • 4,661
  • 1
  • 23
  • 25