В твоём примере используется implicit conversion с типа int в тип double Грубо говоря, почти как new[] { (double)1, 1.5, (double)2, 2.5 } Только неявно. Читать про implicit operators Есть также explicit operators, это уже явная конверсия, чаще всего с потерей данных new[] { 1, (int)1.5, 2, (int)2.5 } - массив int[] из значений 1, 1, 2, 2
Объявление без new это по факту использование литералов, которые поддерживаются в языке. Есть список из примерно 10-15 типов, у которых есть свои литералы, и соответственно с ними принято работать без new. Надо просто заучить. В основном это структуры, исключение - string