CompilationRepresentationFlags.UseNullAsTrueValue
に使用することができます
識別された共用体のnullarydiscriminatorsの表現としてnullの使用を許可する
Option.None
これの最も顕著な例です。
なぜこれが便利なのですか?nullチェックは、ユニオンケース(生成されたTag
プロパティ)をチェックするための従来のメカニズムよりも優れていますか?
それはおそらく予期しない動作につながります:
Some(1).ToString() //"Some(1)"
None.ToString() //NullReferenceException
編集
静的な読み取り専用フィールドの代わりにnullと比較する方が速いというJackの主張をテストしました。
[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
type T<'T> =
| Z
| X of 'T
let t = Z
ILSpyを使用すると、t
(予想どおりに)nullにコンパイルされることがわかります。
public static Test.T<a> t<a>()
{
return null;
}
テスト:
let mutable i = 0
for _ in 1 .. 10000000 do
match t with
| Z -> i <- i + 1
| _ -> ()
結果:
実数:00:00:00.036、CPU:00:00:00.046、GC gen0:0、gen1:0、gen2:0
CompilationRepresentation
属性が削除されると、静的な読み取り専用フィールドになりt
ます。
public static Test.T<a> t<a>()
{
return Test.T<a>.Z;
}
public static Test.T<T> Z
{
[CompilationMapping(SourceConstructFlags.UnionCase, 0)]
get
{
return Test.T<T>._unique_Z;
}
}
internal static readonly Test.T<T> _unique_Z = new Test.T<T>._Z();
そして結果は同じです:
実数:00:00:00.036、CPU:00:00:00.031、GC gen0:0、gen1:0、gen2:0
t == null
パターンマッチは、前者と後者の場合と同様にコンパイルされt is Z
ます。