Nullable micro-optimizations, part oneで、Eric は、似たようなユーザー定義型では実現できない奇妙なボクシング動作があると述べていますNullable<T>
。
C# 言語が定義済みのNullable<T>
型に付与する特別な機能は何ですか? 特に、タイプで動作させることができなかったものMyNullable
。
もちろん、 にNullable<T>
は特別な構文法である sugarT?
がありますが、私の質問はセマンティクスに関するものです。
Nullable micro-optimizations, part oneで、Eric は、似たようなユーザー定義型では実現できない奇妙なボクシング動作があると述べていますNullable<T>
。
C# 言語が定義済みのNullable<T>
型に付与する特別な機能は何ですか? 特に、タイプで動作させることができなかったものMyNullable
。
もちろん、 にNullable<T>
は特別な構文法である sugarT?
がありますが、私の質問はセマンティクスに関するものです。
私が得ていたのは、ボックス化された nullable のようなものはありません。をボックス化するint
と、ボックス化された への参照が取得されますint
。をボックス化するint?
と、null 参照またはボックス化された への参照が取得されますint
。箱入りのint?
.
独自の構造体は簡単に作成できますOptional<T>
が、そのボクシング動作を持つ構造体を実装することはできません。Nullable<T>
の特別な動作はランタイムに組み込まれています。
この事実は、多くの奇妙なことにつながります。例えば:
Nullable<T>
参考までに、タイプが「魔法」である他の方法があります。たとえば、構造体型ですが、構造体の制約を満たしていません。そのプロパティを持つ独自の構造体を作成する方法はありません。
C# は、null 許容型の演算子を持ち上げます。例えば:
int? SumNullableInts(int? a, int? b)
{
return a + b;
}
それをサポートするには、多くのリフレクション作業を行う必要がありMyNullable<T>
、その後、次のようにコンパイルする必要があります。
MyNullable<List<string>.Enumerator> SumNullableEnumerators(MyNullable<List<string>.Enumerator> a, MyNullable<List<string>.Enumerator> b)
{
return a + b;
}
私はC#の仕様でこれら2つを見つけました:
is
演算子は onとT?
同じように動作し、演算子は null 許容型に変換できます。T
as
さて、これに限定されないと私が思う機能は次のNullable<T>
とおりです。
switch
、null 許容型にすることができます。switch は MyNullable 型で定義できるユーザー定義の暗黙的な変換も受け入れるため、これは重要ではないと思います。ここに私が確信していないものがあります: