2012-02-03 14 views
13

yo sólo he dado cuenta de que sólo hay una pequeña diferencia en la declaración de un Estado no miembro de la Unión discriminado:Enum vs no miembros discriminado unión

type Color = 
    | Red 
    | Green 
    | Blue 

y declarando una enumeración:

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

Lo Cuáles son sus principales diferencias en términos de rendimiento, uso, etc.? ¿Tiene alguna sugerencia de cuándo usar qué?

Respuesta

14

Enum son stuctos y, por lo tanto, se asignan en la pila, mientras que las uniones discriminadas son tipos de referencias, por lo que se asignan al montón. Por lo tanto, esperaría que DU fuera un poco menos eficiente que las enumeraciones, aunque en realidad probablemente nunca notará esta diferencia.

Lo que es más importante, una unión discriminada solo puede ser uno de los tipos declarados, ya que las enumeraciones son solo un entero, por lo que podría convertir un entero que no sea miembro de la enumeración enum. Esto significa que cuando coinciden los patrones, el compilador puede afirmar que la coincidencia de patrones está completa cuando cubriste todos los casos para un DU, pero para una enumeración siempre debes poner un caso de captura por defecto, es decir, para una enumeración. Siempre necesitará la coincidencia de patrones como:

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

donde como el último caso no sería necesario con un DU.

Un último punto, ya que las enumeraciones son soportadas nativamente tanto en C# como en VB.NET, ya que las DU no son, las enumeraciones suelen ser una mejor opción cuando se crea una API pública para el consumo en otros idiomas.

6

Además de lo que ha dicho Robert, la coincidencia de patrones en uniones se realiza de dos maneras. Para uniones con solo casos nullary, es decir, casos sin un valor asociado (esto corresponde estrechamente a enumeraciones), se comprueba la propiedad Tag generada por el compilador, que es int. En este caso, puede esperar que el rendimiento sea el mismo que con las enumeraciones. Para los sindicatos que tienen casos no nulary, se utiliza una prueba de tipo, que supongo que también es bastante rápido. Como dijo Robert, si hay una discrepancia en el rendimiento es insignificante. Pero en el primer caso, debería ser exactamente lo mismo.

En cuanto a la "incompletitud" inherente de las enumeraciones, cuando falla una coincidencia de patrones, lo que realmente desea saber es si la coincidencia no cubrió un caso válido. Por lo general, no te importa si un valor entero inválido fue enviado a la enumeración. En ese caso, quiere que la coincidencia falle. Casi siempre prefiero los sindicatos, pero cuando tengo que usar enumeraciones (generalmente para la interoperabilidad), dentro del caso de comodín obligatorio, paso el valor no coincidente a a function that distinguishes between valid and invalid values y aparece el error apropiado.

0

A partir de F # 4.1 hay struct discriminated unions.

Estos tienen los beneficios de rendimiento de asignación de pila, como enumeraciones.

Tienen la coincidencia superior de las uniones discriminadas.

Son específicos de F #, por lo que si necesita ser entendido por otros lenguajes .Net, debe seguir usando enums.

Cuestiones relacionadas