2014-02-09 4 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[]. Подробности см. В разделе 7.5.3 спецификации C# (и у мальчика много деталей).

В частности, из секции 7.5.3.5:

С учетом двух различных типов Т1 и Т2, Т1 является лучшей, чем мишень, преобразующая Т2, если по меньшей мере одно из следующих условий:

  • неявное преобразование от T1 до T2 существует, и не неявное преобразование из Т2 Т1 существует

Это дело здесь, где T1 - double[] и T2 - object. Существует неявное преобразование от double[] до object, но неявное преобразование от object к double[], поэтому double[] - лучшая цель преобразования, чем object.

Если вы хотите заставить использование object конструктора, просто бросил:

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

не 'double []' a 'object'? –

+3

@KhaledAKhunaifer: Да, если перегрузка, принимающая 'double []' * did * *, существовала, она вызывала бы перегрузку, принимающую 'object', но поскольку перегрузка, принимающая' double [] ', более специфична, чем перегрузка 'object', это тот, который выбран. –

19

В основном, double[] является object, но все object s являются неdouble[] s. Как более конкретный вариант, компилятор выбирает его, как наиболее конкретный вариант.

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 

объект [] г не в два раза []. Нет никакого неявного преобразования из объекта в double [].

+2

Несмотря на то, что это истинные наблюдения, этот ответ сам по себе не отвечает на вопрос, почему «новый D (нулевой)» предпочитает конструктор, который он делает. – doppelgreener

Смежные вопросы