Целевые new
выражения
Заметка
Эта статья является спецификацией компонентов. Спецификация служит проектным документом для функции. Она включает предлагаемые изменения спецификации, а также информацию, необходимую во время проектирования и разработки функции. Эти статьи публикуются до тех пор, пока предложенные изменения спецификации не будут завершены и включены в текущую спецификацию ECMA.
Может возникнуть некоторое несоответствие между спецификацией компонентов и завершенной реализацией. Эти различия фиксируются в соответствующем собрании по проектированию языка (LDM) .
Дополнительные сведения о процессе внедрения спецификаций функций в стандарт языка C# см. в статье о спецификациях .
Проблема чемпиона: https://github.com/dotnet/csharplang/issues/100
Сводка
Не требуется спецификация типа для конструкторов, если этот тип известен.
Мотивация
Разрешить инициализацию полей без дублирования типа.
Dictionary<string, List<int>> field = new() {
{ "item1", new() { 1, 2, 3 } }
};
Разрешить опущению типа, когда его можно вывести из использования.
XmlReader.Create(reader, new() { IgnoreWhitespace = true });
Создайте экземпляр объекта без явного указания типа.
private readonly static object s_syncObj = new();
Спецификация
Новая синтаксическая форма target_typed_newobject_creation_expression принимается, при этом тип является необязательным.
object_creation_expression
: 'new' type '(' argument_list? ')' object_or_collection_initializer?
| 'new' type object_or_collection_initializer
| target_typed_new
;
target_typed_new
: 'new' '(' argument_list? ')' object_or_collection_initializer?
;
Выражение target_typed_new не имеет типа. Однако существует новое преобразование создания объектов, которое является неявным преобразованием из выражения, исходящего из target_typed_new для каждого типа.
Для целевого типа T
, тип T0
является базовым типом для T
, если T
является экземпляром System.Nullable
. В противном случае T0
является T
. Значение выражения target_typed_new, преобразованного в тип T
, совпадает со значением соответствующего object_creation_expression, в котором T0
указан в качестве типа.
Это ошибка во время компиляции, если target_typed_new используется как операнд унарного или двоичного оператора, или если оно используется там, где не подлежит преобразованию создания объектов.
Открытый вопрос: нужно ли разрешить делегатам и кортежам быть целевым типом?
Приведенные выше правила включают делегаты (ссылочный тип) и кортежи (тип структуры). Хотя оба типа можно создать, если тип выводим, можно уже использовать анонимную функцию или литерал кортежа.
(int a, int b) t = new(1, 2); // "new" is redundant
Action a = new(() => {}); // "new" is redundant
(int a, int b) t = new(); // OK; same as (0, 0)
Action a = new(); // no constructor found
Разное
Ниже приведены последствия спецификации:
- Разрешено использование
throw new()
(целевой тип —System.Exception
) - Целевой типизированный
new
не допускается с двоичными операторами. - Запрещается, если отсутствует тип для указания цели: унарные операторы, коллекция
foreach
, вusing
, в деконструкции, в выраженииawait
, в виде свойства анонимного типа (new { Prop = new() }
), в инструкцииlock
, вsizeof
, в оператореfixed
, при доступе к члену (new().field
), в динамической отправке операции (someDynamic.Method(new())
), в запросе LINQ, как операнд оператораis
, как левый операнд оператора??
, ... - Она также запрещена как
ref
. - Следующие типы типов не допускаются в качестве целевых объектов преобразования.
-
типы перечисления:
new()
будет работать (так какnew Enum()
работает для предоставления значения по умолчанию), ноnew(1)
не будут работать, так как типы перечисления не имеют конструктора. - типы интерфейса: это будет работать так же, как соответствующее выражение создания для типов COM.
- типы массивов: массивы нуждаются в специальном синтаксисе для предоставления длины.
-
динамический: мы не разрешаем
new dynamic()
, поэтому мы не разрешаемnew()
сdynamic
в качестве целевого типа. - кортежей: они имеют то же значение, что и создание объекта с помощью базового типа.
- Все остальные типы, которые не разрешены в object_creation_expression, также исключаются, например, типы указателей.
-
типы перечисления:
Недостатки
Были некоторые опасения, что целевые типы new
создают новые категории критических изменений, но у нас уже есть это с null
и default
, и это не было значительной трудностью.
Альтернативы
Большинство жалоб на типы слишком долго повторяются в инициализации полей, заключается в том, аргументы типа не самого типа, мы можем вывести только аргументы типа, такие как new Dictionary(...)
(или аналогичные) и выводить аргументы типа локально из аргументов или инициализатора коллекции.
Вопросы
- Следует ли запрещать использование в деревьях выражений? (нет)
- Как функция взаимодействует с аргументами
dynamic
? (никакое специальное лечение) - Как IntelliSense должен работать с
new()
? (только если существует один целевой тип)
Встречи по дизайну
C# feature specifications