2010-01-15 13 views
22

Tengo el siguiente código:¿Por qué "No todas las rutas de código devuelven un valor" con una instrucción switch y una enumeración?

public int Method(MyEnum myEnum) 
{ 
    switch (myEnum) 
    { 
     case MyEnum.Value1: return 1; 
     case MyEnum.Value2: return 2; 
     case MyEnum.Value3: return 3; 
    } 
} 

public enum MyEnum 
{ 
    Value1, 
    Value2, 
    Value3 
} 

y me sale el error: "Not all code paths return a value". No entiendo cómo la declaración switch nunca podría saltar a uno de los casos especificados.

¿Puede un enum de alguna manera ser null?

Respuesta

30

No hay nada que decir que el valor de myEnum será uno de esos valores.

No confundas enums por ser un restrictivo conjunto de valores. Es realmente solo un llamado conjunto de valores. Por ejemplo, podría llamar a su método con:

int x = Method((MyEnum) 127); 

¿Qué le gustaría que hiciera? Si usted quiere que una excepción que puede hacer que en un caso por defecto:

switch (myEnum) 
{ 
    case MyEnum.Value1: return 1; 
    case MyEnum.Value2: return 2; 
    case MyEnum.Value3: return 3; 
    default: throw new ArgumentOutOfRangeException(); 
} 

otra posibilidad es utilizar Enum.IsDefined por adelantado, si usted quiere hacer algún otro trabajo antes de la sentencia switch. Esto tiene la desventaja de boxeo ... hay algunas formas redondas que, pero son generalmente más trabajo ...

muestra:

public int Method(MyEnum myEnum) 
{ 
    if (!IsDefined(typeof(MyEnum), myEnum) 
    { 
     throw new ArgumentOutOfRangeException(...); 
    } 
    // Adjust as necessary, e.g. by adding 1 or whatever 
    return (int) myEnum; 
} 

Esto supone que hay una obvia relación entre el subyacente valores en MyEnum y el valor que desea devolver.

+0

Aha ... Eso explica mucho. Estoy acostumbrado a Java enums. –

+0

@JonSkeet: ¿Podría indicarnos un ejemplo de cómo evitar el boxeo en tales situaciones? Gracias por adelantado. –

+0

@RaheelKhan: consulta https://code.google.com/p/unconstrained-melody/ para ver un ejemplo. –

0

Si cambia los valores en su enumeración (agregando un cuarto) su código se romperá. Debe agregar un valor predeterminado: caso a su declaración de cambio.

por supuesto, la otra manera de lograr esto sería definir los valores enteros en su enumeración ...

public enum MyEnum 
{ 
    Value1 = 1, 
    Value2 = 2, 
    Value3 = 3 
} 

y luego de emitir su enumeración como un int en el código. En lugar de int myInt = Method(myEnumValue); puede usar int myInt = (int)myEnum

+1

Eso no es del todo correcto, vea las otras respuestas. –

+1

El hecho de que mi código se rompa si lo cambio no es el negocio de los compiladores ¿verdad? –

+0

No directamente, no, pero si extiendes mi respuesta con las otras enumeradas a continuación, verás el problema. Línea inferior -> agregue un caso predeterminado al código. – ZombieSheep

5

Las enumeraciones no están limitadas a los valores que representan. Usted puede asignar esto:

MyEnum v = (MyEnum)1000; 

Y no habría ningún problema en absoluto. Agregue un valor predeterminado a su interruptor y manejará todas las situaciones posibles.

-1

Tiene que ser:

public int Method(MyEnum myEnum) 
{ 
    switch (myEnum) 
    { 
     case MyEnum.Value1: return 1; 
     case MyEnum.Value2: return 2; 
     case MyEnum.Value3: return 3; 
     default: return 0; 
    } 
} 

o:

public int Method(MyEnum myEnum) 
{ 
    switch (myEnum) 
    { 
     case MyEnum.Value1: return 1; 
     case MyEnum.Value2: return 2; 
     case MyEnum.Value3: return 3; 
    } 

    return 0; 
} 
+0

o puede lanzar una excepción en el caso de que Enum no sea un valor válido o cualquier otro caso de manejo que desee. –

0
MyEnum blah = 0; 

defecto es siempre 0 y es convertir implícitamente, incluso si usted no tiene uno con un valor de 0.

Cuestiones relacionadas