C#中的模糊函数/构造函数调用

时间:2010-05-19 12:25:29

标签: c# ambiguous-call

以下代码导致编译器错误,因为它是不明确的调用,但是如果我们使用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 个答案:

答案 0 :(得分:16)

如果更改使ArrayListobject的构造函数,则代码正常工作的原因是C#编译器将选择最适用的特定类型。在string / object的情况下,string实际object派生,因此“更具体”并且将由编译器推断。使用stringArrayList,它是苹果和橙子:要么可以为空,要么都不是“特定”而是另一种。

答案 1 :(得分:4)

我可能错了,但我认为将ArrayList更改为object时它的工作原理是因为string继承自object并且它决定使用更具体的字符串版本。当它是字符串和ArrayList时,它不知道使用哪一个。

答案 2 :(得分:3)

null可以代表stringArrayList。没有关于你的方法版本(在这种情况下是构造函数)的信息。

您可以通过强制转换强制它使用特定的:

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)

  1. 当然它含糊不清:null可以是stringArrayList。您需要对其进行限定,例如(string) null
  2. 您是否知道ArrayList已被弃用?您应该使用其中一种通用集合类型

答案 5 :(得分:1)

ArrayListstring都是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)则不会。