Перенести NULL в конструктор

Я не могу понять, почему конструктор выполняется с параметром Double[]?

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, это также ссылочный тип.

Ответ 1

Но я не понимаю, почему нет объекта? Это также ссылочный тип?

Да, оба double[] и object являются ссылочными типами, поэтому null неявно конвертируется в оба из них. Однако перегрузка элементов обычно благоприятствует более конкретным типам, поэтому используется конструктор double[]. Подробности см. В разделе 7.5.3 спецификации С# (и у мальчика много деталей).

В частности, из раздела 7.5.3.5:

Учитывая два разных типа T1 и T2, T1 является лучшей целью преобразования, чем T2, если выполняется хотя бы одно из следующих действий:

  • Существует неявное преобразование из T1 в T2, и не существует никакого неявного преобразования из T2 в T1.

В этом случае здесь T1 double[] и T2 есть object. Там неявное преобразование от double[] до object, но неявное преобразование от object до double[], поэтому double[] является лучшей целью преобразования, чем object.

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

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

Ответ 2

В принципе, double[] - это object, но все object не double[] s. Поскольку double[] более конкретный вариант, компилятор выбирает его, как наиболее конкретный.

Ответ 3

Рассмотрим это:

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

double [] d - объект.

Итак, рассмотрим следующее:

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

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