2014-02-09 154 views
60

我不明白为什么使用参数Double[]执行构造函数?将NULL传递给构造函数

using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace MyConsoleApp 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      D myD = new D(null); 
      Console.ReadLine();   
     } 

    } 

    public class D 
    { 
     public D(object o) 
     { 
      Console.WriteLine("Object"); 
     } 
     public D(double[] array) 
     { 
      Console.WriteLine("Array"); 
     } 
     public D(int i) 
     { 
      Console.WriteLine("Int"); 
     } 
    } 
} 

我想因为第一个构造函数需要引用类型的参数。具有引用参数的第一个构造函数是因为null是引用类型的默认值。

但我不明白为什么不object,它也是一个引用类型。

+12

你在这里要求麻烦。如果你打算使用重载,包含一般类型作为对象会导致在某个点 –

+1

@DavidHeffernan IDK的痛苦。大多数情况下,我认为调用哪种方法相当直观。只有在没有别的东西可以被调用时才会调用对象。直觉上这是有道理的,因为相反将是无稽之谈 – Cruncher

+2

这是一个很好的面试问题! :) –

回答

90

但我不明白为什么没有对象?这也是一个参考类型?

是的,无论是double[]object是引用类型,所以null隐式转换为两者。但是,成员重载通常更偏向于更具体的类型,因此使用构造函数double[]。有关更多详细信息,请参阅C#规范的第7.5.3节(和男孩有很多细节)。

特别是,从节7.5.3.5:

鉴于两种不同类型的T1和T2,T1比T2更好的转换目标如果以下中的至少一个成立:

  • 从T1到T2的隐式转换存在,并从T2到T1的隐式转换存在

那这里的情况,其中T1double[]T2object。存在从double[]object的隐式转换,但没有从objectdouble[]的隐式转换,所以double[]是比object更好的转换目标。

如果你想强制使用object构造的,只投:

D myD = new D((object) null); 
+0

是不是'double []''对象'? –

+3

@KhaledAKhunaifer:是的,所以如果超载采用'double []'*不存在,它会调用'object'的超载 - 但是因为采用'double []'的超载比超载更具体'对象',那是被挑选的那个。 –

19

基本上,double[]object,但所有object s为double[]秒。由于double[]是更具体的选项,编译器会选择它作为最具体的选项。

2

考虑一下:

double[] d = new double[] {}; 
Console.WriteLine(d is object);//output is True 

双[] d是一个对象。

所以,可以这样考虑:

object z = new object[] {}; 
Console.WriteLine(z is double[]);//output is False 

对象[] z不能翻倍[]。 没有将对象隐式转换为double []。

+2

尽管这些都是真实的观察结果,但这个答案本身并不能回答为什么'new D(null)'更喜欢它所做的构造函数。 – doppelgreener