Неоднозначная функция/вызов конструктора в 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);
        }
7
задан Ahmed Said 19 May 2010 в 12:25
поделиться

5 ответов

Причина, по которой код работает нормально, если вы измените конструктор, который принимает ArrayList для принятия объекта , заключается в том, что компилятор C# выберет наиболее конкретный тип. В случае string/object, string на самом деле производно от object и поэтому является «более конкретным» и будет выведен компилятором. С string против ArrayList это яблоки и апельсины: любой из них может быть пустым, но ни один из них не является более «специфическим», чем другой.

16
ответ дан 6 December 2019 в 06:35
поделиться

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

4
ответ дан 6 December 2019 в 06:35
поделиться

ArrayList и строка оба типа допускающие значение NULL . Это сбивает компилятор с толку.

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

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

например:

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

}

Этот код компилирует но если вы измените public A (int x) t на public A (int? x) , этого не произойдет.

1
ответ дан 6 December 2019 в 06:35
поделиться
  1. Конечно, это неоднозначно: null может быть либо строкой , либо ArrayList . Вам нужно будет указать его, например (строка) null .
  2. Знаете ли вы, что ArrayList устарел? Вместо этого следует использовать один из общих типов коллекций
1
ответ дан 6 December 2019 в 06:35
поделиться

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

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

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

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

3
ответ дан 6 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: