ターゲット型の newTarget-typed new expressions

  • [x] が提案されています[x] Proposed
  • [x] プロトタイプ[x] Prototype
  • [] の実装[ ] Implementation
  • [] 仕様[ ] Specification

まとめSummary

型がわかっている場合は、コンストラクターの型指定を必要としません。Do not require type specification for constructors when the type is known.

目的Motivation

型を複製せずにフィールドの初期化を許可します。Allow field initialization without duplicating the type.

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

使用法から推論できる場合は、型の省略を許可します。Allow omitting the type when it can be inferred from usage.

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

型のスペルを修正せずにオブジェクトをインスタンス化します。Instantiate an object without spelling out the type.

private readonly static object s_syncObj = new();

仕様Specification

Object_creation_expressiontarget_typed_new 新しい構文形式が受け入れられます。この は省略可能です。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?
    ;

Target_typed_new 式に型がありません。A target_typed_new expression does not have a type. ただし、新しい オブジェクト作成変換 は、 target_typed_new からすべての型に存在する式からの暗黙的な変換です。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.

対象の型を指定した T T0 場合、 T がのインスタンスである場合、型は基になる型になり T System.Nullable ます。Given a target type T, the type T0 is T's underlying type if T is an instance of System.Nullable. それ以外 T0 の場合は TOtherwise T0 is T. 型に変換される target_typed_new 式の意味 T は、型としてを指定する、対応する object_creation_expression の意味と同じです T0The 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.

単項演算子または二項演算子のオペランドとして target_typed_new が使用されている場合、または オブジェクトの作成変換 の対象とならない場所で使用されている場合は、コンパイル時エラーになります。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.

懸案事項を開く: デリゲートとタプルをターゲットタイプとして許可する必要がありますか。Open Issue: should we allow delegates and tuples as the target-type?

上記の規則には、デリゲート (参照型) と組 (構造体型) が含まれます。The above rules include delegates (a reference type) and tuples (a struct type). どちらの型も構築可能ですが、型が inferable の場合は、匿名関数またはタプルリテラルを使用できます。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

その他Miscellaneous

仕様の結果は次のようになります。The following are consequences of the specification:

  • throw new() は許可されています (対象の型はです System.Exception )throw new() is allowed (the target type is System.Exception)
  • ターゲット型 new は、二項演算子では使用できません。Target-typed new is not allowed with binary operators.
  • ターゲットにする型がない場合は許可されません。演算子のオペランドとして、演算子のオペランドとして、動的にディスパッチされた操作 () では、LINQ クエリでは、() 内の、分解内では、ステートメント内では、ステートメント内では、型の単項演算子、のコレクションは、演算子のオペランドとして foreach using await new { Prop = new() } lock sizeof fixed new().field someDynamic.Method(new()) is ?? ...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, ...
  • としても許可されてい ref ません。It is also disallowed as a ref.
  • 次の種類の型は、変換のターゲットとして許可されていません。The following kinds of types are not permitted as targets of the conversion
    • 列挙型: new() は ( new Enum() 既定値を指定するために動作しますが) 機能しますが、 new(1) 列挙型にコンストラクターがないため機能しません。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.
    • インターフェイスの種類: これは、COM 型の対応する作成式と同じように動作します。Interface types: This would work the same as the corresponding creation expression for COM types.
    • 配列型: 配列の長さを指定するには、特別な構文が必要です。Array types: arrays need a special syntax to provide the length.
    • 動的: 許可さ new dynamic() れていないため、 new()dynamic 対象の型として使用することはできません。dynamic: we don't allow new dynamic(), so we don't allow new() with dynamic as a target type.
    • タプル: これらは、基になる型を使用したオブジェクトの作成と同じ意味を持ちます。tuples: These have the same meaning as an object creation using the underlying type.
    • Object_creation_expression で許可されていないその他のすべての型も、ポインター型など、除外されます。All the other types that are not permitted in the object_creation_expression are excluded as well, for instance, pointer types.

デメリットDrawbacks

互換性に影響する変更の新しいカテゴリを作成することには、いくつかの問題がありましたが、既にとを使用していて、それが new null default 重大な問題ではありませんでした。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.

代替Alternatives

フィールドの初期化時に型引数が長すぎることに関する不満のほとんどは、型自体で はない型 引数に関するものであり、型引数 new Dictionary(...) (または同様) を推論し、引数またはコレクション初期化子からローカルで型引数を推論することができます。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.

質問Questions

  • 式ツリーで使用できないようにする必要がありますか。Should we forbid usages in expression trees? 番号(no)
  • 機能が引数と対話する方法 dynamicHow the feature interacts with dynamic arguments? (特別な処理はありません)(no special treatment)
  • IntelliSense new() の操作方法How IntelliSense should work with new()? (1 つのターゲット型がある場合のみ)(only when there is a single target-type)

会議のデザインDesign meetings