2012-08-15 8 views
11

tengo una enumeración como:¿Por qué necesitamos conversión de tipo enum en C#

public enum Test:int 
{ 
    A=1, 
    B=2 
} 

Así que aquí Sé que mi enumeración es un tipo int, pero si quiero hacer algo como lo siguiente:

int a = Test.A; 

Esto no funciona.

Si tengo una clase como:

public class MyTest 
{ 
    public static int A =1; 
} 

lo que puedo decir,

int a = MyTest.A; 

Aquí no necesito a emitir A a int explícitamente.

+0

http://stackoverflow.com/questions/97391/how-to-get-the-underlying-value-of-an-enum – 2kay

+2

Es una opción de diseño. Creo que los inventores de C# piensan que es más seguro y/o más legible. –

+0

¿Qué razón convincente existiría para este escenario? –

Respuesta

3

Con tu ejemplo actualización:

public class MyTest 
{ 
    public static int A =1; 
} 

y uso:

int a = MyTest.A; 

Eso es no cómo enumeraciones Mira. Las enumeraciones se parecen más a (los comentarios son lugares en los que difieren de una enumeración real):

public struct MyTest /* Of course, this isn't correct, because we'll inherit from System.ValueType. An enum should inherit from System.Enum */ 
{ 
    private int _value; /* Should be marked to be treated specially */ 
    private MyTest(int value) /* Doesn't need to exist, since there's some CLR fiddling */ 
    { 
     _value = value; 
    } 

    public static explicit operator int(MyTest value) /* CLR provides conversions automatically */ 
    { 
     return value._value; 
    } 
    public static explicit operator MyTest(int value) /* CLR provides conversions automatically */ 
    { 
     return new MyTest(value); 
    } 

    public static readonly MyTest A = new MyTest(1); /* Should be const, not readonly, but we can't do a const of a custom type in C#. Also, is magically implicitly converted without calling a constructor */ 

    public static readonly MyTest B = new MyTest(2); /* Ditto */ 
} 

Sí, puede fácilmente llegar al "subyacente" valor int, pero los valores de A y B son todavía fuertemente escrito como del tipo MyTest. Esto asegura que no accidentalmente los usa en lugares donde no son apropiados.

+0

Es un buen ejemplo, gracias, ahora entiendo por qué tengo que hacer el casting. Significa que tengo que hacer unboxing cada vez que uso el valor. –

+0

Es * no * cómo se ven las enumeraciones, porque puede convertir * cualquier * 'valor int 'en una enumeración con un valor subyacente de ese tipo. Los mensajes son "inseguros" en ese sentido, desafortunadamente. Además, son tipos de valores en lugar de tipos de referencia. –

+1

@Praveen: No, eso no significa que tengas que hacer unboxing. La conversión de un valor enum a su valor numérico no implica boxeo o unboxing en absoluto. –

18

Así que aquí Sé que mi enumeración es un tipo int

No, no lo es. Tiene un subyacente tipo de int, pero es un tipo separado. Diablos, eso es la mitad del punto de tener enumeraciones en primer lugar, que puede mantener los tipos separados.

Cuando desea convertir entre un valor enum y su equivalente numérico, emite - no es tan doloroso, y mantiene su código más limpio en términos de seguridad de tipo. Básicamente, es una de esas cosas en las que la rareza de que sea la derecha lo que hace que sea apropiado hacerlo explícito.

EDIT: Una rareza que usted debe tener en cuenta es que hay es una conversión implícita del valor constante 0 al tipo de enumeración:

Test foo = 0; 

De hecho, en la implementación de MS, lo que puede ser cualquier tipo de constante 0:

Test surprise = 0.0; 

Eso es un error, pero que es demasiado tarde para arreglar :)

Creo que el resto de esta conversión implícita fue para simplificar la comprobación de si los bits están configurados en una lista de banderas, y otras comparaciones que usarían "el valor 0". Personalmente, no soy partidario de esa decisión, pero al menos es importante conocerla.

+0

Quiero decir, sé que la enumeración es int, ¿no es tan confuso que puedo decir que mi enumeración tiene subyacente tipo int pero no puedo usarlo como int. –

+2

@Praveen: No, la enumeración no es int. La enumeración tiene una * representación de almacenamiento * de int, pero es un tipo separado. Usted * no debe * usarlo como una int sin hacerlo explícitamente ... –

+1

@Praveen: * "Sé que la enumeración es int" * - Intuitivamente entiende que está representando un 'int', sí. Pero en lo que respecta al compilador, es un tipo diferente. Al igual que si creas una clase que no tiene otro miembro que un solo público 'int'. Usted "sabe que es solo un' int' ", pero en realidad es un tipo completamente diferente que simplemente representa internamente su único miembro de datos como' int'. – David

3

Los valores enum no son del tipo int. int es el tipo de base de la enumeración. Las enumeraciones son técnicamente ints pero lógicamente (desde la perspectiva del lenguaje C#) no. int (System.Int32) es el tipo base de todas las enumeraciones de forma predeterminada, si no especificas explícitamente otra.

2

You enum es del tipo Test. No es int solo porque su enumeración tiene valores enteros.

Puede emitir su enumeración para obtener el valor int:

int a = (int) Test.A; 
+0

Que sé que puedo lanzarlo, pero la pregunta es ¿por qué tengo que lanzarlo? –

+0

Supongo que es una decisión de diseño que nos echen explícitamente. – davenewza

Cuestiones relacionadas