В скомпилированном коде F # использует значение null
для представления None
случая option<'T>
для эффективности. На самом деле вы можете использовать то же самое для своих собственных дискриминационных союзов, используя флаг компиляции CompilationRepresentationFlags.
UseNullAsTrueValue
(см. документация MSDN ).
Вы можете видеть, что это происходит используя метод Object.ReferenceEquals
:
> let n = None;;
val n : 'a option
> System.Object.ReferenceEquals(n, null);;
val it : bool = true
Почему printfn "%A"
просто печатает внутреннее представление, а не признает, что это на самом деле представляет None
случай?
Я думаю, что ответ эта печать выполняется динамически с использованием отражения, поэтому в какой-то момент аргумент просто преобразуется в значение типа obj
. Если у вас есть значение null
типа obj
, невозможно восстановить тип, который был до приведения, и поэтому вы не можете обнаружить, что null
фактически представляет None
(потому что null.GetType()
не удается). Предположительно, печать могла бы использовать информацию о типе stati c для получения информации о типе таким образом, но это, вероятно, было бы более сложно реализовать.