Enum vs нечлен-дискриминационный союз - PullRequest
13 голосов
/ 03 февраля 2012

Я только что заметил, что есть только небольшая разница в объявлении недискриминационного объединения:

type Color =
    | Red
    | Green
    | Blue

и объявлении enum:

type Color =
    | Red = 0 
    | Green = 1
    | Blue = 2

различия с точки зрения производительности, использования и т. д.?У вас есть предложения, когда что использовать?

Ответы [ 3 ]

14 голосов
/ 03 февраля 2012

Перечисления являются структурами и, следовательно, размещаются в стеке, в то время как распознаваемые объединения являются ссылочными типами, поэтому выделяется куча. Таким образом, вы ожидаете, что DU будет немного менее производительным, чем перечисления, хотя в действительности вы, вероятно, никогда не заметите эту разницу.

Что еще более важно, дискриминируемое объединение может быть только одним из объявленных типов, где перечисления на самом деле просто целые числа, так что вы можете привести целое число, которое не является членом перечисления, к типу перечисления Это означает, что когда сопоставление с образцом компилятор может утверждать, что сопоставление с образцом завершено, когда вы рассмотрели все случаи для DU, но для перечисления вы должны всегда помещать в перехват по умолчанию все остальные случаи, то есть Вам всегда нужно сопоставление с образцом, например:

match enumColor with
| Red -> 1 
| Green -> 2
| Blue -> 3
| _ -> failwith "not an enum member"

где в последнем случае нет необходимости с DU.

И последний момент, поскольку перечисления изначально поддерживаются как в C #, так и в VB.NET, а в отличие от DU, перечисления часто являются лучшим выбором при создании общедоступного API для использования другими языками.

6 голосов
/ 03 февраля 2012

В дополнение к тому, что сказал Роберт, сопоставление с образцом в профсоюзах выполняется одним из двух способов.Для объединений с только нулевыми падежами, то есть для случаев без ассоциированного значения (это близко соответствует перечислениям), проверяется сгенерированное компилятором свойство Tag, которое является int.В этом случае вы можете ожидать, что производительность будет такой же, как с перечислениями.Для союзов, имеющих ненулевые случаи, используется тест типа, который, я полагаю, также довольно быстрый.Как сказал Роберт, если есть несоответствие производительности, оно незначительно.Но в первом случае все должно быть точно так же.

Что касается присущей "неполноте" перечислений, когда совпадение с образцом не удается, то вы действительно хотите знать, если действительный случай не был покрыт совпадением,Как правило, вас не волнует, было ли неверное целочисленное значение приведено к перечислению.В этом случае вы хотите, чтобы матч провалился.Я почти всегда предпочитаю союзы, но когда мне нужно использовать перечисления (обычно для взаимодействия), внутри обязательного подстановочного знака я передаю несопоставленное значение в функцию, которая различает действительные и недействительные значения и вызывает соответствующую ошибку.

0 голосов
/ 04 января 2018

Начиная с F # 4.1, существует структурированных союзов .

. Они имеют преимущества в производительности при распределении стека, как перечисления.

Они имеют превосходящее соответствие распознаваемыхсоюзы.

Они специфичны для F #, поэтому, если вам нужно понимать другие языки .Net, вы все равно должны использовать перечисления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...