Я думаю, что в целом это высокий порядок, потому что перечисления "слабые". ConsoleSpecialKey
является хорошим примером "полного" перечисления, где ControlC
и ControlBreak
, которые представлены соответственно 0 и 1, являются единственными значимыми значениями, которые он может принимать. Но у нас есть проблема, вы можете привести любое целое число к ConsoleSpecialKey
!:
let x = ConsoleSpecialKey.Parse(typeof<ConsoleSpecialKey>, "32") :?> ConsoleSpecialKey
Так что шаблон, который вы дали, на самом деле неполон и действительно требует обработки.
( не говоря уже о более сложных перечислениях, таких как System.Reflection.BindingFlags
, которые используются для маскировки битов и все же неразличимы в информации о типах из простых перечислений, что еще больше усложняет картину edit: фактически, @ildjarn указал из-за того, что атрибут Flags используется, как правило, для различения полных и битовых перечислений, хотя компилятор не помешает вам использовать побитовые операции для перечислений, не помеченных этим атрибутом, снова выявляя слабые стороны из перечислений ).
Но если вы работаете с определенным "полным" перечислением, таким как ConsoleSpecialKey
, и пишете, что последний случай неполного совпадения с образцом все время действительно вас беспокоит, вы всегда можете получить полный активный шаблон:
let (|ControlC|ControlBreak|) value =
match value with
| ConsoleSpecialKey.ControlC -> ControlC
| ConsoleSpecialKey.ControlBreak -> ControlBreak
| _ -> Enum.unexpected value
//complete
match value with
| ControlC -> ()
| ControlBreak -> ()
Однако это все равно, что просто оставить необработанный случай сопоставления с образцом необработанным и подавить предупреждение. Я думаю, что ваше текущее решение хорошо, и вам было бы хорошо просто придерживаться его.