У меня вопрос по использованию new[].
Представьте себе это:
Object.SomeProperty = new[] {"string1", "string2"};
Где SomeProperty ожидает массив строк.
Я знаю, что этот фрагмент кода будет работать. Но я хочу знать, что он делает под капотом. Создает ли new[] экземпляр класса object, а в SomeProperty он автоматически преобразует его в объект string?
Спасибо





Это просто синтаксический сахар. Компилятор определит тип, действительно необходимый здесь, и создаст код, эквивалентный явной конструкции:
Object.SomeProperty = new string[] {"string1", "string2"};
Не существует такой вещи, как new[], которая запускается во время выполнения.
Компилятор заменяет:
Object.SomeProperty = new[] {"string1", "string2"};
с:
Object.SomeProperty = new string[] {"string1", "string2"};
инициализация, являющаяся инициализацией переменной. например. строка [] foo = {"бар", "баз"};
Это примерно переводится на:
string[] $temp = new string[2];
$temp[0] = "string1";
$temp[1] = "string2";
Object.SomeProperty = $temp;
Интересно, что var x = new[] { "string1", "string2" }; тоже работает, он может сделать вывод, что x - это string[], но var x = { "string1", "string2" }; не работает.
Это потому, что массив является ссылочным типом, который должен быть выделен с помощью new. Ничто не будет синтаксически приукрашивать это.
Да, но когда задан тип, синтаксис, отличный от new[], обновляет тип, передавая IEnumerable <T>, поэтому, когда он имеет только var, почему он не мог в последний раз отказаться от значения по умолчанию для T []?
Я очень надеюсь, что из вашего ответа вы не запутались между заменой типа и выводом типа здесь! Я предполагаю, что тип Object.SomeProperty - string [], хотя из-за ковариации массива это может быть object [] (обратите внимание, что нет будет хорошей вещью - проверьте Сообщение Эрика Липперта по этому вопросу!).
Компилятор выполняет вывод типа с использованием эвристики - он определяет, что «строка1» и «строка2» относятся к типу строки, и поэтому эффективно заменяет ваш код на: -
Object.SomeProperty = new string[] {"string1", "string2"};
Это действительно так просто! Все это делается во время компиляции, ничего во время выполнения.
Хорошо, здесь все еще есть некоторая путаница, связанная с маленький.
Вывод, который происходит, не имеет ничего общего с типом Object.SomeProperty, но все связано с типами выражений в инициализаторе массива. Другими словами, вы могли:
object o = new[] { "string1", "string2" };
и o по-прежнему будет ссылкой на массив строк.
По сути, компилятор смотрит на такое выражение:
new[] { A, B, C, D, ... }
(где A, B, C, D и т. д. - выражения) и пытается определить правильный тип массива для использования. Он рассматривает только типы A, B, C и D (и т. д.) Как тип элемента массива. Взяв этот набор типов-кандидатов, он пытается найти тот, в который можно неявно преобразовать все остальные. Если такого типа нет ровно один, то компилятор пожалуется.
Так например:
new[] { new Form(), new MemoryStream() }
не компилируется - ни MemoryStream, ни Form не могут быть преобразованы в другой. Тем не мение:
new[] { GetSomeIDisposable(), new MemoryStream() }
будет рассматриваться как IDisposable[], потому что существует неявное преобразование из MemoryStream в IDisposable. Так же:
new[] { 0, 1, 3.5 } // double[]
new[] { 1, 3, 100L } // long[]
Object.SomeProperty = {"строка1", "строка2"}; Ни в одном компиляторе C#, который я когда-либо видел! Это можно сделать только во время инициализации.