Неоднозначный вызов функции / конструктора в 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));
- конечно, это неоднозначно:
null
может бытьstring
илиArrayList
. Вам нужно будет квалифицировать его, как(string) null
. - вы знали, что
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)
не будет.