以下代码导致编译器错误,因为它是不明确的调用,但是如果我们使用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);
}
答案 0 :(得分:16)
如果更改使ArrayList
取object
的构造函数,则代码正常工作的原因是C#编译器将选择最适用的特定类型。在string
/ object
的情况下,string
实际从object
派生,因此“更具体”并且将由编译器推断。使用string
与ArrayList
,它是苹果和橙子:要么可以为空,要么都不是“特定”而是另一种。
答案 1 :(得分:4)
我可能错了,但我认为将ArrayList更改为object时它的工作原理是因为string继承自object并且它决定使用更具体的字符串版本。当它是字符串和ArrayList时,它不知道使用哪一个。
答案 2 :(得分:3)
null
可以代表string
或ArrayList
。没有关于你的方法版本(在这种情况下是构造函数)的信息。
您可以通过强制转换强制它使用特定的:
static void Main(string[] args)
{
A o = new A((string)null);
}
...或者交替实现一个行为符合你想要的构造函数(不带参数)
答案 3 :(得分:2)
您可以使用默认关键字来解决这种情况,代码将为:
A o = new A(default(ArrayList));
或者
A o = new A(default(string));
答案 4 :(得分:1)
null
可以是string
或ArrayList
。您需要对其进行限定,例如(string) null
。ArrayList
已被弃用?您应该使用其中一种通用集合类型答案 5 :(得分:1)
ArrayList
和string
都是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
更改为public A(int? x)
则不会。