Expressions de type cible newTarget-typed new expressions

  • [x] proposé[x] Proposed
  • [x] prototype[x] Prototype
  • [] Implémentation[ ] Implementation
  • [] Spécification[ ] Specification

RésuméSummary

Ne requièrent pas de spécification de type pour les constructeurs lorsque le type est connu.Do not require type specification for constructors when the type is known.

MotivationMotivation

Autorisez l’initialisation des champs sans dupliquer le type.Allow field initialization without duplicating the type.

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

Autoriser l’omission du type lorsqu’il peut être déduit de l’utilisation.Allow omitting the type when it can be inferred from usage.

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

Instanciez un objet sans épeler le type.Instantiate an object without spelling out the type.

private readonly static object s_syncObj = new();

CaractéristiqueSpecification

Une nouvelle forme syntaxique, target_typed_new de la object_creation_expression est acceptée dans laquelle le type est facultatif.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?
    ;

Une expression target_typed_new n’a pas de type.A target_typed_new expression does not have a type. Toutefois, il existe une nouvelle conversion de création d’objet qui est une conversion implicite à partir d’une expression, qui existe d’un target_typed_new à chaque type.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.

Pour un type de cible donné T , le type T0 est T sous-jacent du type si T est une instance de System.Nullable .Given a target type T, the type T0 is T's underlying type if T is an instance of System.Nullable. Sinon, T0 est T .Otherwise T0 is T. La signification d’une expression target_typed_new qui est convertie vers le type T est la même que la signification d’un object_creation_expression correspondant qui spécifie T0 comme type.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.

Il s’agit d’une erreur au moment de la compilation si un target_typed_new est utilisé comme opérande d’un opérateur unaire ou binaire, ou s’il est utilisé là où il n’est pas soumis à une conversion de création d’objet.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.

Problème d’ouverture : devons-nous autoriser les délégués et les tuples en tant que type cible ?Open Issue: should we allow delegates and tuples as the target-type?

Les règles ci-dessus incluent les délégués (type référence) et les tuples (type struct).The above rules include delegates (a reference type) and tuples (a struct type). Bien que les deux types soient constructible, si le type est déduire, une fonction anonyme ou un littéral de tuple peut déjà être utilisé.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

DiversMiscellaneous

Les conséquences de la spécification sont les suivantes :The following are consequences of the specification:

  • throw new() est autorisé (le type cible est System.Exception )throw new() is allowed (the target type is System.Exception)
  • Le type cible new n’est pas autorisé avec les opérateurs binaires.Target-typed new is not allowed with binary operators.
  • Elle n’est pas autorisée lorsqu’il n’y a aucun type à cibler : opérateurs unaires, collection d’un, dans un foreach using , dans une déconstruction, dans une await expression, en tant que propriété de type anonyme (), dans une instruction, dans une instruction, dans un new { Prop = new() } accès de membre (), dans une lock sizeof fixed new().field opération distribuée dynamiquement ( someDynamic.Method(new()) ), dans une requête LINQ, en tant qu’opérande de l' is opérateur, comme opérande gauche de l' ?? opérateur,...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, ...
  • Il est également interdit en tant que ref .It is also disallowed as a ref.
  • Les genres de types suivants ne sont pas autorisés en tant que cibles de la conversionThe following kinds of types are not permitted as targets of the conversion
    • Types enum : new() fonctionnera (car new Enum() fonctionne pour fournir la valeur par défaut), mais ne new(1) fonctionnera pas, car les types enum n’ont pas de constructeur.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.
    • Types d’interface : Cela fonctionnerait de la même façon que l’expression de création correspondante pour les types COM.Interface types: This would work the same as the corresponding creation expression for COM types.
    • Types tableau : les tableaux ont besoin d’une syntaxe spéciale pour fournir la longueur.Array types: arrays need a special syntax to provide the length.
    • dynamique : nous n’autorisons pas new dynamic() , donc nous n’autorisons pas new() avec dynamic comme type de cible.dynamic: we don't allow new dynamic(), so we don't allow new() with dynamic as a target type.
    • tuples : Celles-ci ont la même signification que la création d’un objet à l’aide du type sous-jacent.tuples: These have the same meaning as an object creation using the underlying type.
    • Tous les autres types qui ne sont pas autorisés dans le object_creation_expression sont également exclus, par exemple les types pointeur.All the other types that are not permitted in the object_creation_expression are excluded as well, for instance, pointer types.

InconvénientsDrawbacks

Certains problèmes liés à la création de nouvelles catégories de modifications avec rupture ont été apportés par la cible new , mais nous en avons déjà null un avec et default , et cela n’a pas été un problème significatif.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.

Autres solutionsAlternatives

La plupart des plaintes sur les types trop longs pour être dupliqués dans l’initialisation de champ concerne les arguments de type qui ne sont pas le type lui-même, mais nous pourrions déduire uniquement les arguments de type comme new Dictionary(...) (ou similaires) et déduire les arguments de type localement à partir des arguments ou de l’initialiseur de collection.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.

QuestionsQuestions

  • Devons-nous interdire les utilisations dans les arborescences d’expressions ?Should we forbid usages in expression trees? º(no)
  • Comment la fonctionnalité interagit-elle avec les dynamic arguments ?How the feature interacts with dynamic arguments? (aucun traitement spécial)(no special treatment)
  • Comment IntelliSense doit-il fonctionner new() ?How IntelliSense should work with new()? (uniquement s’il existe un seul type cible)(only when there is a single target-type)

Réunions de conceptionDesign meetings