ValueTypenull
がそのdefault(T)
これは良い洞察ですが、心配する必要はありません。すでに説明済みです。default(T)
そもそも T を使用と比較することは正当ではありません==
。==
オーバーロードの解決では、一意の最適な演算子は見つかりません。
もちろん、比較を行うことはできますが.Equals
、レシーバーが null の場合にクラッシュするリスクがあります。これは、まさに回避しようとしているものです。
この状況を処理するためのより標準的な方法はありますか?
いいえ、null と比較するのは正しいことです。
C# 仕様のセクション 7.10.6 で述べられているように、「 T が値型を表すことができても、x == null
構造体は許可されます。T が値型の場合、結果は単純に false と定義されます。」
このことから問題が発生する可能性はありますか?
もちろん。コードがコンパイルされたからといって、意図したセマンティクスがあるとは限りません。いくつかのテストを書きます。
呼び出しを行って値の型を渡すと、内部で実際に何が起こるのでしょうか?
質問があいまいです。2 つの質問に言い換えてみましょう。
Null 非許容値型である型引数を使用してジェネリック メソッドを呼び出すと、内部で実際に何が起こるのでしょうか?
ジッタは、最初の呼び出しでメソッドをその構造でコンパイルします。ジッターがヌル チェックを検出すると、それを「false」に置き換えます。これは、null を許容しない値の型が null と等しくなることはないことがわかっているためです。
型引数が参照型で、引数が構造体型であるジェネリック メソッドを呼び出すと、内部で実際に何が起こるのでしょうか? 例えば:
interface IFoo : ISomeInterface<IFoo> {}
struct SFoo : IFoo { whatever }
...
DoFooInternal<IFoo>(new SFoo());
その場合、ジッタはヌル チェックを回避できず、コール サイトはボクシングを回避できません。SFoo インスタンスがボックス化され、ボックス化された SFoo への参照が null かどうかがチェックされます。