CompilationRepresentationFlags.UseNullAsTrueValue
可以用来
允许使用 null 作为可区分联合中的 null 鉴别器的表示形式
Option.None
是这方面最突出的例子。
为什么这很有用?与检查联合案例(生成的Tag
属性)的传统机制相比,空检查如何更好?
它可能会导致意想不到的行为:
Some(1).ToString() //"Some(1)"
None.ToString() //NullReferenceException
编辑
我测试了 Jack 的断言,即与 null 而不是静态只读字段相比更快。
[<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
后一种情况进行编译。