Solution 1:

But I can not understand why no object? It's also a reference type?

Yes, both double[] and object are reference types, so null is implicitly convertible to both of them. However, member overloading generally favours more specific types, so the double[] constructor is used. See section 7.5.3 of the C# specification for more details (and boy are there a lot of details).

In particular, from section 7.5.3.5:

Given two different types T1 and T2, T1 is a better conversion target than T2 if at least one of the following holds:

  • An implicit conversion from T1 to T2 exists, and no implicit conversion from T2 to T1 exists

That's the case here, where T1 is double[] and T2 is object. There's an implicit conversion from double[] to object, but no implicit conversion from object to double[], so double[] is a better conversion target than object.

If you want force the use of the object constructor, just cast:

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

Solution 2:

Basically, double[] is an object, but all objects are not double[]s. As double[]'s the more specific option, the compiler chooses it, as the most specific one.

Solution 3:

Consider this:

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

double[] d is an object.

So consider this:

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

object[] z are not double[]. There is no implicit conversion from object to double[].