次の方法で共有


Null 合体演算子割り当て

メモ

この記事は機能仕様についてです。 仕様は、機能の設計ドキュメントとして使用できます。 これには、提案された仕様の変更および機能の設計と開発時に必要な情報が含まれます。 これらの記事は、提案された仕様の変更が決定され、現在の ECMA 仕様に組み込まれるまで公開されます。

機能の仕様と行われた実装では、いくつかの違いがあることがあります。 これらの違いは、関連する言語設計ミーティング (LDM) メモに取り上げられています。

機能仕様を C# 言語標準に導入するプロセスの詳細については、仕様に関する記事を参照してください。

チャンピオンの課題: https://github.com/dotnet/csharplang/issues/34

まとめ

変数が null の場合に値が割り当てられる一般的なコーディング パターンを簡略化します。

この提案の一環として、型が制約されていない型パラメーターである式を左側で使用できるように ?? の型要件も緩和します。

目的

フォームのコードが表示されるのが一般的です

if (variable == null)
{
    variable = expression;
}

この提案では、この関数を実行する言語に、オーバーロードできない二項演算子を追加します。

この機能には、少なくとも 8 つの個別のコミュニティ要求があります。

詳細な設計

新しいフォームの代入演算子を追加します

assignment_operator
    : '??='
    ;

これは、複合代入演算子 (§12.21.4) の既存のセマンティック ルールに従います。ただし、左側が null 以外の場合は代入を省略します。 この機能のルールは次のとおりです。

a ??= bでは、Aaの型であり、Bbの型であり、もし A0 が null 許容値型である場合、AA の基になる型です。

  1. A が存在しない場合、または null 非許容値型の場合は、コンパイル時エラーが発生します。
  2. B が暗黙的に A または A0 に変換できない場合 (A0 が存在する場合)、コンパイル時エラーが発生します。
  3. A0 が存在し、B が暗黙的に A0に変換でき、かつ B が動的でない場合、a ??= b の型は A0です。 a ??= b は実行時に次のように評価されます。
    var tmp = a.GetValueOrDefault();
    if (!a.HasValue) { tmp = b; a = tmp; }
    tmp
    
    ただし、 a が評価されるのは 1 回のみです。
  4. それ以外の場合、 a ??= b の型は Aです。 a ??= b は実行時に a ?? (a = b)として評価されます。ただし、 a が評価されるのは 1 回のみです。

??の型要件を緩和するために、a ?? bAの型であることを前提とするaに関する仕様を更新します。

  1. A が存在し、null 許容型または参照型でない場合、コンパイル時エラーが発生します。

この要件は、次の場合に緩和されます。

  1. A が存在し、null 非許容値型の場合、コンパイル時エラーが発生します。

これにより、制約されていない型パラメーター T が存在し、null 許容型ではなく、かつ参照型ではないため、null 合体演算子は制約されていない型パラメーターで機能します。

デメリット

他の言語機能と同様、この機能の恩恵を受ける C# プログラムの内容に明確性が追加されることで、言語に対する複雑さが相殺されるかどうかを疑問に思う必要があります。

代替

プログラマは、手動で (x = x ?? y)if (x == null) x = y;、または x ?? (x = y) を記述できます。

未解決の質問

  • [ ] &&= 演算子と ||= 演算子もサポートする必要がありますか?

デザイン会議

なし。