Вопрос
У меня есть вопрос по поводу использования new[]
.
Представьте себе это:
Object.SomeProperty = new[] {"string1", "string2"};
Где SomeProperty ожидает массив строк.
Я знаю, что этот фрагмент кода будет работать.Но я хочу знать, что он делает под капотом.Делает new[]
создает экземпляр класса object
и в SomeProperty
он автоматически преобразует его в string
возражать?
Спасибо
Решение
Ладно, все еще есть маленький здесь небольшая путаница.
Вывод, который происходит, не имеет ничего общего с типом объекта.SomeProperty , но все связано с типами выражений в инициализаторе массива.Другими словами, вы могли бы сделать:
object o = new[] { "string1", "string2" };
и o по-прежнему будет ссылкой на строковый массив.
По сути, компилятор просматривает выражение, подобное этому:
new[] { A, B, C, D, ... }
(где A, B, C, D и т.д. Являются выражениями) и пытается определить правильный тип массива для использования.Он рассматривает только типы A, B, C и D (etc) в качестве типа элемента массива.Взяв этот набор типов-кандидатов, он пытается найти тот, в который все остальные могут быть неявно преобразованы.Если там нет ровно один такой тип, после чего компилятор будет жаловаться.
Так, например:
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 = new string[] {"string1", "string2"};
Нет такой вещи, как new[]
это выполняется во время выполнения.
Это примерно переводится как:
string[] $temp = new string[2];
$temp[0] = "string1";
$temp[1] = "string2";
Object.SomeProperty = $temp;
Интересно, var x = new[] { "string1", "string2" };
работает также, он может вывести x как a string[]
, но var x = { "string1", "string2" };
терпит неудачу.
Компилятор заменяет:
Object.SomeProperty = new[] {"string1", "string2"};
с:
Object.SomeProperty = new string[] {"string1", "string2"};
Я очень надеюсь, что из вашего ответа вы не путаетесь между подстановкой типов и выводом типов здесь!Я предполагаю тип объекта.SomeProperty - это string[] , хотя из-за ковариации массива это может быть object[] (обратите внимание, что это будет не будь хорошей вещью - проверь Сообщение Эрика Липперта на эту тему!).
Компилятор выполняет вывод типа с использованием эвристики - он определяет, что "string1" и "string2" имеют тип string, и поэтому он эффективно заменяет ваш код на:-
Object.SomeProperty = new string[] {"string1", "string2"};
Это действительно так просто!Все это делается во время компиляции, ничего во время выполнения.