Итак, читая спецификацию, первая подсказка здесь
b) Типы с нулевым значением в качестве ненормального значения.Это типы, которые не допускают нулевого литерала, но имеют нулевое значение как ненормальное значение.
Типы в этой категории:
o Весь список F #, запись, кортеж, функция, класси типы интерфейсов.
o Все типы объединения F #, кроме тех, для которых в качестве нормального значения указано значение null (как описано в следующем абзаце).
Для этих типов использование литерала null имеет видпрямо не разрешеноОднако, строго говоря, можно сгенерировать нулевое значение для этих типов, используя определенные функции, такие как Unchecked.defaultof.Для этих типов ноль считается ненормальным значением.Поведение операций по отношению к нулевым значениям определено в §6.9.
Это, по-видимому, предполагает, что при передаче нулевого значения для вашего объединения может быть какое-то неопределенное поведение, так как значение«ненормальный», раздел 6.9 не особенно полезен
Глядя на определение _
, кажется, что вы правы, что это ошибка - она гласит
7.1.7 Шаблоны подстановочных знаков
Шаблон _ является шаблоном подстановочных знаков и соответствует любому входу.Например:
позвольте категоризировать x =
match x with
| 1 -> 0
| 0 -> 1
| _ -> 0
Я думаю, что самые важные подсказки, хотя позже, где перечислены скомпилированные методы для DU, перечислены
8.5.3 Скомпилированная форма типов объединения для использования на других языках CLI
Скомпилированный тип объединения U будет иметь:
· Одно свойство статического геттера CLI UC для каждого случая нулевого объединения C.Это приведет к получению одноэлементного объекта, представляющего этот случай.
· Один вложенный тип CLI UC для каждого случая ненулевого объединения C. Этот тип будет иметь свойства экземпляра Item1, Item2 .... для каждого поля объединенияcase или свойство экземпляра Item, если имеется только одно поле.Скомпилированный тип объединения только с одним случаем не имеет вложенного типа.Вместо этого сам тип объединения играет роль типа case.
· Один статический метод CLI U.NewC для каждого ненулевого случая объединения C. Это создаст объект для этого случая.
· Одно свойство экземпляра CLI u.IsC для каждого случая C, которое возвращает true или false для случая.
· Одно свойство экземпляра CLI u.Tag для каждого случая C, которое выбирает или вычисляет целочисленный тег, соответствующийcase.
Из этого вы можете видеть, что все методы для проверки являются методами экземпляра, которые требуют ненулевого значения.Синус null
является "ненормальным", сгенерированный код не беспокоит проверки, поэтому он выдает.
Я думаю, вы могли бы утверждать, что это на самом деле ошибка, основанная на определении _
.Однако для его исправления потребуется вставлять нулевые проверки перед каждой проверкой соответствия шаблону DU, что значительно замедлит код, поэтому я сомневаюсь, будет ли это исправлено