次の方法で共有


ターゲットにより型指定された条件式

手記

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

機能の仕様と完成した実装の間には、いくつかの違いがある可能性があります。 これらの違いは、関連する 言語設計会議 (LDM) ノートでキャプチャされます。

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

条件式の変換

条件式 c ? e1 : e2の場合、

  1. e1e2に共通の型はありません。
  2. 共通型が存在するが、e1 または e2 の式の 1 つに、その型への暗黙的な変換がない

新しい暗黙的な 条件式変換 を定義します。条件式から、e1 から T への変換、および e2 から Tへの変換がある任意の型 T への暗黙的な変換が可能になります。 条件式に e1e2 の間に共通の型がなく、条件式変換の対象になっていない場合は、エラーになります。

式からの変換の向上

私たちは変わります

式からの変換の向上

E から型 T1に変換する暗黙的な変換 C1 と、式 E から型 T2に変換する暗黙的な変換 C2 を考えると、C1 は、ET2 と完全に一致せず、少なくとも次の 1 つが保持されている場合、C2 よりも 優れた変換 です。

  • と完全に一致します ( §12.6.4.5)
  • T1 は、T2 (§12.6.4.7) よりも優れた変換ターゲットです

送信先

式からの変換の向上

E から型 T1に変換する暗黙的な変換 C1 と、式 E から型 T2に変換する暗黙的な変換 C2 を考えると、C1 は、ET2 と完全に一致せず、少なくとも次の 1 つが保持されている場合、C2 よりも 優れた変換 です。

  • と完全に一致します ( §12.6.4.5)
  • C1条件式変換 ではなく、C2条件式変換です。
  • T1 は、T2 (§12.6.4.7) よりも優れた変換ターゲットであり、C1C2 はどちらも の条件式変換 であるか、条件式変換でもありません。

キャスト式

現在の C# 言語仕様では、

形式 (T)Ecast_expression (Tで、Eunary_expression) は、E の値の明示的な変換 (§10.3) を T の型にします。

条件式変換 の場合、E から Tへの変換が複数存在する可能性があります。 条件式変換を追加すると、条件式変換への他の変換が優先され、最後の手段としてのみ 条件式変換が使用されます。

デザイン ノート

変更の理由は、例えばこのようなケースを処理するために、式 からの変換をより良くすることです。

M(b ? 1 : 2);

void M(short);
void M(long);

このアプローチには、2 つの小さな欠点があります。 まず、switch 式とまったく同じではありません。

M(b ? 1 : 2); // calls M(long)
M(b switch { true => 1, false => 2 }); // calls M(short)

これは依然として破壊的変更ですが、そのスコープが実際のプログラムに影響を与える可能性は低くなります。

M(b ? 1 : 2, 1); // calls M(long, long) without this feature; ambiguous with this feature.

M(short, short);
M(long, long);

これは、最初の引数の long への変換が (条件式変換を使用しないため) あいまいになりますが、2 番目の引数では short への変換が適しています (shortlongよりも 変換ターゲットの が優れているためです)。 この破壊的変更は、既存のプログラムの動作をサイレントモードで変更しないため、あまり深刻ではないようです。

キャスト式に関するメモの理由は、次のようなケースを処理するためです。

_ = (short)(b ? 1 : 2);

このプログラムは現在、int から shortへの明示的な変換を使用しており、このプログラムの現在の言語の意味を保持したいと考えています。 変更は実行時には観察できませんが、次のプログラムでは変更を監視できます。

_ = (A)(b ? c : d);

ここで、c は型 Cd は型 Dで、C から Dへの暗黙的なユーザー定義変換、および D から Aへの暗黙的なユーザー定義変換、および C から Aへの暗黙的なユーザー定義変換があります。 このコードが C# 9.0 より前にコンパイルされている場合、b が true の場合、c から D に変換し、Aに変換します。 条件式変換を使用する場合、b が true の場合、c から A に直接変換され、異なる一連のユーザー コードが実行されます。 したがって、既存の動作を維持するために、条件式変換 をキャストの最後の手段として扱います。