1. ホーム
  2. c#

[解決済み] var/nullを使ったスイッチのおかしな動作

2023-03-14 18:25:17

質問

次のようなコードがあるとします。

string someString = null;
switch (someString)
{
    case string s:
        Console.WriteLine("string s");
        break;
    case var o:
        Console.WriteLine("var o");
        break;
    default:
        Console.WriteLine("default");
        break;
}

なぜswitch文のマッチングは case var o ?

私の理解では case string s は一致しません。 s == null というのは、(事実上) (null as string) != null は false と評価されるからです。VS Codeのインテリセンスでは ostring も同様です。何かご意見はありますか?


に似ています。 C# 7 ヌルチェックによるスイッチケース

どのように解決するのですか?

パターンマッチの内部 switch 文の中で case を使うことは、その値が特定の型か派生型かを尋ねていることになります。 これは次のものと全く同じです。 is

switch (someString) {
  case string s:
}
if (someString is string) 

null は型を持たないので、上記のいずれの条件も満たしません。 静的な型である someString の静的型はどちらの例にも当てはまりません。

var を含むすべての値にマッチしますが、パターンマッチではワイルドカードとして機能します。 null .

default のケースはデッドコードです。 この case var o は null か non-null に関わらずどんな値にもマッチします。 デフォルトでないケースは常にデフォルトのケースに勝ります。 default は決してヒットしません。 ILを見れば、それが出力されていないことがわかるでしょう。

一見したところ、これが警告なしでコンパイルされるのは奇妙に思えるかもしれません (間違いなく私は投げ出されました)。 しかし、これは 1.0 にさかのぼる C# の動作と一致しています。 コンパイラは default がヒットしないことが自明な場合でも、コンパイラはを許可します。 例として次のようなものを考えてみましょう。

bool b = ...;
switch (b) {
  case true: ...
  case false: ...
  default: ...
}

ここで default は決してヒットしません(たとえ bool でさえも)ヒットすることはありません。 しかし、C#は1.0から警告なしにこれを許可しています。 パターン マッチングは、ここではこの動作に沿ったものになっているだけです。