Expresiones de tipo de destino newTarget-typed new expressions

  • [x] propuesto[x] Proposed
  • [x] prototipo[x] Prototype
  • [] Implementación[ ] Implementation
  • [] Especificación[ ] Specification

ResumenSummary

No es necesario especificar la especificación de tipo para los constructores cuando se conoce el tipo.Do not require type specification for constructors when the type is known.

MotivaciónMotivation

Permite la inicialización de campos sin duplicar el tipo.Allow field initialization without duplicating the type.

Dictionary<string, List<int>> field = new() {
    { "item1", new() { 1, 2, 3 } }
};

Permite omitir el tipo cuando se puede inferir del uso.Allow omitting the type when it can be inferred from usage.

XmlReader.Create(reader, new() { IgnoreWhitespace = true });

Cree una instancia de un objeto sin deletrear el tipo.Instantiate an object without spelling out the type.

private readonly static object s_syncObj = new();

EspecificaciónSpecification

Nueva forma sintáctica, target_typed_new de la object_creation_expression se acepta en la que el tipo es opcional.A new syntactic form, target_typed_new of the object_creation_expression is accepted in which the type is optional.

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?
    ;

Una expresión target_typed_new no tiene un tipo.A target_typed_new expression does not have a type. Sin embargo, hay una nueva conversión de creación de objetos que es una conversión implícita de la expresión, que existe de una target_typed_new a cada tipo.However, there is a new object creation conversion that is an implicit conversion from expression, that exists from a target_typed_new to every type.

Dado un tipo T de destino, el tipo T0 es el T tipo subyacente si T es una instancia de System.Nullable .Given a target type T, the type T0 is T's underlying type if T is an instance of System.Nullable. De lo contrario, T0 es T .Otherwise T0 is T. El significado de una expresión target_typed_new que se convierte al tipo T es el mismo que el significado de una object_creation_expression correspondiente que especifica T0 como el tipo.The meaning of a target_typed_new expression that is converted to the type T is the same as the meaning of a corresponding object_creation_expression that specifies T0 as the type.

Es un error en tiempo de compilación si se utiliza un target_typed_new como operando de un operador unario o binario, o si se utiliza cuando no está sujeto a una conversión de creación de objeto.It is a compile-time error if a target_typed_new is used as an operand of a unary or binary operator, or if it is used where it is not subject to an object creation conversion.

Problema de apertura: ¿se deben permitir los delegados y las tuplas como tipo de destino?Open Issue: should we allow delegates and tuples as the target-type?

Las reglas anteriores incluyen delegados (un tipo de referencia) y tuplas (un tipo de estructura).The above rules include delegates (a reference type) and tuples (a struct type). Aunque ambos tipos se pueden construir, si el tipo es inferido, ya se puede usar una función anónima o un literal de tupla.Although both types are constructible, if the type is inferable, an anonymous function or a tuple literal can already be used.

(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

VariosMiscellaneous

Las siguientes son las consecuencias de la especificación:The following are consequences of the specification:

  • throw new() está permitido (el tipo de destino es System.Exception )throw new() is allowed (the target type is System.Exception)
  • No se permite el tipo de destino new con operadores binarios.Target-typed new is not allowed with binary operators.
  • No se permite cuando no hay ningún tipo para el destino: operadores unarios, colección de un foreach , en un using , en una desconstrucción, en una await expresión, como una propiedad de tipo anónimo (), en una instrucción, en una instrucción, en un new { Prop = new() } lock acceso de sizeof fixed miembro ( new().field ), en una operación distribuida dinámicamente ( someDynamic.Method(new()) ), en una consulta LINQ, como operando del is operador, como operando izquierdo del ?? operador,...It is disallowed when there is no type to target: unary operators, collection of a foreach, in a using, in a deconstruction, in an await expression, as an anonymous type property (new { Prop = new() }), in a lock statement, in a sizeof, in a fixed statement, in a member access (new().field), in a dynamically dispatched operation (someDynamic.Method(new())), in a LINQ query, as the operand of the is operator, as the left operand of the ?? operator, ...
  • Tampoco se permite como ref .It is also disallowed as a ref.
  • No se permiten los siguientes tipos de tipos como destinos de la conversiónThe following kinds of types are not permitted as targets of the conversion
    • Tipos de enumeración: new() funcionará (como new Enum() funciona para proporcionar el valor predeterminado), pero new(1) no funcionará porque los tipos de enumeración no tienen un constructor.Enum types: new() will work (as new Enum() works to give the default value), but new(1) will not work as enum types do not have a constructor.
    • Tipos de interfaz: Esto funcionaría igual que la expresión de creación correspondiente para los tipos COM.Interface types: This would work the same as the corresponding creation expression for COM types.
    • Tipos de matriz: las matrices necesitan una sintaxis especial para proporcionar la longitud.Array types: arrays need a special syntax to provide the length.
    • dinámico: no se permite new dynamic() , por lo que no se permite new() con dynamic como tipo de destino.dynamic: we don't allow new dynamic(), so we don't allow new() with dynamic as a target type.
    • tuplas: Tienen el mismo significado que la creación de un objeto utilizando el tipo subyacente.tuples: These have the same meaning as an object creation using the underlying type.
    • Todos los demás tipos que no se permiten en el object_creation_expression también se excluyen, por ejemplo, los tipos de puntero.All the other types that are not permitted in the object_creation_expression are excluded as well, for instance, pointer types.

InconvenientesDrawbacks

Había algunos problemas con el tipo de destino new que creaba nuevas categorías de cambios importantes, pero ya lo tenemos con null y default , y eso no ha sido un problema importante.There were some concerns with target-typed new creating new categories of breaking changes, but we already have that with null and default, and that has not been a significant problem.

AlternativasAlternatives

La mayoría de las quejas acerca de los tipos que son demasiado largos para duplicarlos en la inicialización de campos es acerca de los argumentos de tipo que no son del tipo en sí, solo se podían inferir argumentos de tipo como new Dictionary(...) (o similares) e inferir argumentos de tipo localmente a partir de argumentos o del inicializador de colección.Most of complaints about types being too long to duplicate in field initialization is about type arguments not the type itself, we could infer only type arguments like new Dictionary(...) (or similar) and infer type arguments locally from arguments or the collection initializer.

PreguntasQuestions

  • ¿Se deben prohibir los usos en los árboles de expresión?Should we forbid usages in expression trees? ninguno(no)
  • ¿Cómo interactúa la característica con los dynamic argumentos?How the feature interacts with dynamic arguments? (sin tratamiento especial)(no special treatment)
  • ¿Cómo debe trabajar IntelliSense new() ?How IntelliSense should work with new()? (solo cuando hay un solo tipo de destino)(only when there is a single target-type)

Design MeetingsDesign meetings