Ahmed
Ahmed

Reputation: 7238

Ambiguous function/constructor call in C#

The following code causes a compiler error, as it is ambiguous call but the problem if we use object instead of ArrayList no error happens and the string version works fine; Do you have an explanation for that?

class A
{
    public A(string x)
    {
        Console.WriteLine("string");
    }
    public A(ArrayList x)
    {
        Console.WriteLine("ArrayList");
    }

}
    static void Main(string[] args)
        {
            A o = new A(null);
        }

Upvotes: 7

Views: 2898

Answers (6)

Faheem Ijaz
Faheem Ijaz

Reputation: 21

you can tackle this situation by using default keyword like, and the code will be:

A o = new A(default(ArrayList)); 

Or

A o = new A(default(string)); 

Upvotes: 2

Pratik Deoghare
Pratik Deoghare

Reputation: 37172

ArrayList and string are both nullable types. That confuses compiler.

If you have two constructors say one that takes nullable type e.g. ArrayList and other that takes non-nullable type e.g. int. The code will compile and choose the constructor with nullable type.

But if you have more that one constructor that takes nullable type then like @Dan Tao said it's apples and oranges: either can be null, but neither is more "specific" than the other.

for example:

class A
{
    public A(int x)
    {
        Console.WriteLine("string");
    }
    public A(ArrayList x)
    {
        Console.WriteLine("ArrayList");
    }

}

This code compiles but if you change public A(int x)t to public A(int? x) it will NOT.

Upvotes: 1

Dan Tao
Dan Tao

Reputation: 128317

The reason your code works fine if you change the constructor that takes an ArrayList to take an object is that the C# compiler will pick the most specific type applicable. In the case of string/object, string actually derives from object and is therefore "more specific" and will be inferred by the compiler. With string versus ArrayList, it's apples and oranges: either can be null, but neither is more "specific" than the other.

Upvotes: 16

juharr
juharr

Reputation: 32266

I could be wrong, but I think the reason it works when you change ArrayList to object is because string inherits from object and it decides to use the more specific string version. When it's string and ArrayList it doesn't know which one to use.

Upvotes: 4

John Saunders
John Saunders

Reputation: 161773

  1. Of course it's ambiguous: null could be either a string or an ArrayList. You'll need to qualify it, like (string) null.
  2. Did you know that ArrayList is deprecated? You should use one of the generic collection types instead

Upvotes: 1

Rowland Shaw
Rowland Shaw

Reputation: 38130

null could represent either a string, or an ArrayList. There's no information there is to which version of the method (in this case a constructor) you meant.

You can force it to use a specific one by casting:

static void Main(string[] args)
    {
        A o = new A((string)null);
    }

...or alternately implementing a constructor that behaves as you want (that takes no parameter)

Upvotes: 3

Related Questions