[解決済み] なぜis演算子はnullを与えるとfalseを返すのですか?
質問
どうやら
is
演算子は少し矛盾しています。
bool Test()
{
// Returns false, but should return true.
return null is string;
}
期待されるのは
null
の値は任意の参照(または null 可能)型に属すると予想されます。そして実際、C#言語仕様はこの仮説を裏付けるようなことを、例えば(6.1.6 Implicit reference conversions)述べています。
暗黙的な参照変換は
...
- nullリテラルから任意の参照型へ。
の説明(7.10.10 The is演算子)は、以下のようになります。
is
演算子の説明では、まず式
(E is T)
からの参照変換が行われたときに真になることを示します。
E
から
T
が存在する場合、著者らは続けて、明示的に
E
が
null
リテラルであるか
null
の値です。
なぜそのようなことをするのでしょうか?私には直感に反しているように思えます。
どのように解決するのですか?
この質問は 2013年5月30日の私のブログの主題でした。 . 素晴らしい質問をありがとうございました。
あなたは誰もいない車道を見つめています。
誰かがあなたに、「あなたの私道にはホンダのシビックが停まるのか?
はい、はい、できます。
誰かが第二の車道を指さす。それも空っぽです。彼らは、「私の私道の現在の内容は、あなたの私道に収まりますか」と尋ねます。
はい、もちろんです。両方の車道は空です! なぜなら、そもそもどちらにも中身がないのですから。
誰かがあなたに、「あなたの私道にはホンダのシビックがありますか」と尋ねます。
いいえ、入っていません。
あなたが考えているのは
is
演算子が2番目の質問に答えます。
この値が与えられたら、その型の変数に収まるか?
null参照は、この型の変数に収まるか?はい、そうです。
という質問ではありません。
is
演算子が答える問題ではありません。演算子が答える質問は
is
演算子が答える質問は、3番目の質問です。
y is X
は"を尋ねない。
は
y
型の変数の正当な値である
X
?
"を問うものである。
は
y
型のオブジェクトへの有効な参照か?
X
?
への有効な参照ではないので、NULL参照は
のいずれかになります。
オブジェクトの
任意の
型のオブジェクトの場合、答えは「no" 」です。その私道は空っぽで、ホンダ シビックは入っていません。
別の見方をすると
y is X
という質問に答えるものです。
y as X
と言った場合、非 null の結果が得られるでしょうか? y が null の場合、答えは明らかに「いいえ」です!
あなたの質問をもう少し深く見るために
NULL値が参照(またはNULL可能)な型に属していることを期待します。
人は暗黙のうちに タイプ は 値のセット であり、その 割り当ての互換性 は、X型の変数に値yを代入することで、以下のようになります。 yがセットxのメンバーであるかどうかをチェックする .
これは型を見る上で非常に一般的な方法ですが、これは だけです。 ではありませんし、C#が型を見る方法でもありません。C#では、Null参照はどの型にも属さないメンバです。 代入の互換性 は ではなく は、単にセットに値が含まれているかどうかをチェックするだけです。ただ、ヌル参照は 代入互換性がある という関係と "is assign compatible with" 関係は明らかに多くの重複がありますが、CLR では同一ではありません。
もし型理論についての考察に興味があるなら、このテーマについての私の最近の記事をチェックしてください。
関連
-
[解決済み】指定されたキャストが有効でない?
-
[解決済み】Ajax処理で「無効なJSONプリミティブ」と表示される件
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み】非静的メソッドはターゲットを必要とする
-
[解決済み] C#の[Flags]Enum属性の意味とは?
-
[解決済み] EqualsメソッドがオーバーライドされたときにGetHashCodeをオーバーライドすることが重要な理由は何ですか?
-
[解決済み] NULL-COALESCING 演算子のカスタム暗黙変換の不思議な挙動
-
[解決済み] C#で演算子==はジェネリック型に適用できない?
-
[解決済み】"as "とnullable型によるパフォーマンスの驚き
-
[解決済み】Nullable型をジェネリックパラメータにすることは可能か?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】"出力タイプがクラスライブラリのプロジェクトは直接起動できない"
-
[解決済み】Ajax処理で「無効なJSONプリミティブ」と表示される件
-
[解決済み] 'SubSonic.Schema .DatabaseColumn' 型のオブジェクトをシリアライズする際に、循環参照が検出されました。
-
[解決済み】Sequence contains no matching element(シーケンスにマッチする要素がない
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】Entity FrameworkからのSqlException - セッション内で他のスレッドが動作しているため、新しいトランザクションは許可されません。
-
[解決済み】「...は'型'であり、与えられたコンテキストでは有効ではありません」を解決するにはどうすればよいですか?(C#)
-
[解決済み] 2つのリストを結合する
-
[解決済み】エラー「必要なフォーマルパラメータに対応する引数が与えられていない」を解決する?
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。