Неоднозначный вызов функции / конструктора в C#

следующий код вызывает ошибку компилятора, так как он неоднозначный вызов, но проблема, если мы используем object вместо ArrayList ошибка не происходит и string версия работает нормально; у вас есть объяснение этому?

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);
        }

6 ответов


причина, по которой ваш код работает нормально, если вы измените конструктор, который принимает ArrayList взять object заключается в том, что компилятор C# выберет наиболее конкретный тип. В случае string/object, string на самом деле выводит С object и поэтому является "более конкретным" и будет выведен компилятором. С string и ArrayList, Это яблоки и апельсины: либо может быть null, но ни один из них не является более "конкретным", чем другой.


Я могу ошибаться, но я думаю, что причина, по которой он работает при изменении ArrayList на object, заключается в том, что string наследуется от object и решает использовать более конкретную строковую версию. Когда это string и ArrayList, он не знает, какой из них использовать.


null может представлять собой либо string или ArrayList. Нет никакой информации о том, какую версию метода (в данном случае конструктора) вы имели в виду.

вы можете заставить его использовать конкретный литья:

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

...или поочередно реализует конструктор, который ведет себя так, как вы хотите (который не принимает никаких параметров)


вы можете справиться с этой ситуацией, используя по умолчанию ключевое слово, и код будет такой:

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

или

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

  1. конечно, это неоднозначно: null может быть string или ArrayList. Вам нужно будет квалифицировать его, как (string) null.
  2. вы знали, что ArrayList осуждается? Вместо этого следует использовать один из универсальных типов коллекций

ArrayList и string как nullable типы. Это смущает компилятор.

если у вас есть два конструктора, скажем, один, который принимает тип nullable, например ArrayList и другое, что занимает non-nullable тип например int. Код будет составлять и выберите конструктор с nullable тип.

но если у вас больше одного конструктора, который принимает nullable тип то вроде @Dan Tao сказал это яблоки и апельсины: либо может быть null, но ни один не является более "конкретным", чем другие.

например:

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

}

Этот код компилируется но если вы измените public A(int x)t to public A(int? x) не будет.