2011-12-30 15 views
5

Entiendo que las enumeraciones se compilan como constantes, por lo que al cambiarlas se produce un cambio radical. Lo que me pregunto es por qué no se compilaron los Enums de la misma manera que las variables estáticas de solo lectura en su lugar?¿Por qué los Enums se compilaron como constantes en lugar de valores estáticos?

+1

Enum valores no pueden cambiar en tiempo de ejecución de la misma manera const canto.Si fueran estáticos eso implicaría que su valor podría cambiar. –

Respuesta

6

Pueden ser más eficientes que los campos, por lo que no hay necesidad de compilarlos de la misma manera cuando se pueden incrustar directamente en la IL.

[Enumerar] se cargan en la misma forma con la que se carga el valor de const. Se incrustan directamente en el IL. Los campos, por otro lado, requieren una instrucción de carga de campo (ldsfld) que afectará un poco el rendimiento. Los enumerados son por lo tanto tan rápido como const en el uso típico; los campos son algo más lentos

(Source)

+0

Ok, casi fue una decisión basada en el rendimiento. Esto es exactamente lo que estaba buscando ... la respuesta al "¿Por qué?". –

1

De enum (C# Reference)

igual que con cualquier constante, todas las referencias a los valores individuales de una enumeración se convierten a los literales numéricos en tiempo de compilación

Entonces, ¿me estoy perdiendo algo?

+0

Sí. La pregunta era "¿Por qué se compilan como constantes en lugar de readonlys estáticos?" ... Básicamente, ¿cuál fue la decisión de diseño para convertirlos en literales constantes en lugar de readonlys estáticos? –

+0

@my, si no me equivoco, solo se puede configurar en la instanciación, y no es lo mismo que las constantes que no se pueden establecer en la instanciación –

8

Ambas respuestas dadas son técnicamente correctas, pero omiten la explicación para diferenciar constantes con estática (solo lectura). En C#, las constantes son siempre más rápido que de sólo lectura y la razón es muy simple y expresa mejor con un pequeño ejemplo de código:

const int MyConstant = 10; 
static readonly int MyReadonly = 20; 

static void Main() 
{ 
    int result = MyConstant + MyReadonly; 
    // the above statement will be resolved to: 
    // int result = 10 + MyReadonly 
} 

En tiempo de compilación, el compilador reemplaza todas las referencias a una constante con el valor real de esa constante . Puede hacerlo porque una constante debe estar predefinida en tiempo de compilación. Esto difiere de los valores estáticos de solo lectura que, aunque estáticos, en realidad se resuelven en tiempo de ejecución. Tomemos el siguiente ejemplo:

static readonly Encoding = Encoding.GetEncoding("GB2132"); 

No hay manera para que el compilador sabe si GB2132 existe realmente en la máquina en la que está destinado este código se ejecute. La única forma de resolver este valor es en tiempo de ejecución. Static garantiza que el valor en sí no está vinculado a la duración de una instancia y de solo lectura asegura que el valor solo se puede establecer una vez. No hay forma de que el compilador reemplace las referencias a este campo en tiempo de compilación ya que simplemente no se puede conocer el valor.

Lógicamente, solo los tipos primitivos se pueden marcar como constantes.

Ahora en caso de enums, es muy simple. Los mensajes no son más que valores enteros con una etiqueta. Por lo que el siguiente código:

enum MyEnum 
{ 
    First, 
    Second, 
    Third 
} 

static void Main() 
{ 
    MyEnum test = MyEnum.First; 

    if (test == MyEnum.Second) 
    { 
     // whatever 
    } 
} 

será resuelta por el compilador para:

const int MyEnum_First = 0; 
const int MyEnum_Second = 1; 
const int MyEnum_Third = 2; 

static void Main() 
{ 
    int test = MyEnum_First; 

    if (test == MyEnum_Second) 
    { 
     // whatever 
    } 
} 

que a su vez significa que las referencias reales a los campos constantes se puede reemplazar con el valor conocido en tiempo de compilación, por lo que la versión final del código algo así como:

static void Main() 
{ 
    int test = 0; 

    if (test == 1) 
    { 
     // whatever 
    } 
} 
+0

Explicación impresionante, amigo – ivowiblo

+0

Sí, pero la pregunta no era por qué los enums están rompiendo cambios, pero por qué Microsoft eligió compilarlos como constantes en lugar de campos estáticos de solo lectura. Podrían haber hecho que el compilador fuera en cualquier caso, la pregunta era por qué iban con constantes cuando eso sería un cambio radical, y alguien respondía ... simplemente por el aumento del rendimiento. –

Cuestiones relacionadas