2012-05-21 11 views
19

que estoy tratando de construir función genérica que recibe de la cadena de usuario y tratar de analizarlo a Enum valuse así:Cómo usar Tryparse genérico con Enum?

private Enum getEnumStringEnumType(Type i_EnumType) 
    { 
     string userInputString = string.Empty; 
     Enum resultInputType; 
     bool enumParseResult = false; 

     while (!enumParseResult) 
     {     
      userInputString = System.Console.ReadLine(); 
      enumParseResult = Enum.TryParse(userInputString, true, out resultInputType); 
     } 
    } 

pero me sale:

The type 'System.Enum' must be a non-nullable value type in order to use it as parameter 'TEnum' in the generic type or method 'System.Enum.TryParse<TEnum>(string, bool, out TEnum) . 

El error significa que necesito para descartar un Enum específico para resultInputType? ¿Cómo puedo solucionar esto? Gracias.

+0

Cuando dice "función genérica", su método * no es * genérico. ¿Necesita poder especificar el tipo como un valor 'Tipo' en lugar de hacer que este sea un verdadero método genérico? –

Respuesta

37

El TryParse method tiene la siguiente firma:

TryParse<TEnum>(string value, bool ignoreCase, out TEnum result) 
    where TEnum : struct 

Tiene un parámetro de tipo genérico TEnum que debe ser un struct y que es utilizado para determinar el tipo de enumeración siendo analizada. Cuando no lo proporciona explícitamente (como lo hizo), tomará el tipo de lo que proporcione como el argumento result, que en su caso es del tipo Enum (y no el tipo de la enumeración en sí).

Tenga en cuenta que Enum is a class (a pesar de que la herencia de ValueType) y por lo tanto no satisface el requisito de que TEnum es una estructura .

Puede resolver esto eliminando el parámetro Type y dando al método un parámetro de tipo genérico con las mismas restricciones (es decir struct) como el parámetro de tipo genérico en la función de TryParse.

Así que trate de esto, donde yo he llamado el parámetro de tipo genérico TEnum:

private static TEnum GetEnumStringEnumType<TEnum>() 
    where TEnum : struct 
{ 
    string userInputString = string.Empty; 
    TEnum resultInputType = default(TEnum); 
    bool enumParseResult = false; 

    while (!enumParseResult) 
    {     
     userInputString = System.Console.ReadLine(); 
     enumParseResult = Enum.TryParse(userInputString, true, out resultInputType); 
    } 
    return resultInputType; 
} 

Para llamar al método, de uso:

GetEnumStringEnumType<MyEnum>(); 
+0

Enum.TryParse es genérico ... http://msdn.microsoft.com/en-us/library/system.enum.aspx – eyossi

+0

Eso es correcto. Nunca dije que no. Su firma es 'TryParse (valor de cadena, bool ignoreCase, out TEnum result) donde TEnum: struct, new()', y si especifica 'result' usará el tipo de esa variable para determinar' TEnum', guardándolo de especificarlo explícitamente. – Virtlink

+1

Me da el mismo error: el tipo 'TEnum' debe ser un tipo de valor que no admite nulos para usarlo como parámetro 'TEnum' en el tipo genérico o método 'System.Enum.TryParse (string, bool, out TEnum) – Rami

2

Enum.TryParse es un método genérico, lo que significa que sus parámetros de tipo genérico deben conocerse en tiempo de compilación. Esto a su vez significa que sí, debe declarar resultInputType como un tipo de enumeración específico para el código a compilar.

Si usted piensa en él, el código original es un poco demasiado optimista: en ninguna parte dice tipo de enumeración, que debe ser revisado por un miembro con el nombre igual a userInputString. ¿Cómo podría funcionar TryParse sin esta información?

4

debe hacer un método genérico:

private T getEnumStringEnumType<T>() where T : struct, IConvertible 
    { 
     string userInputString = string.Empty; 
     T resultInputType = default(T); 
     bool enumParseResult = false; 

     while (!enumParseResult) 
     { 
      userInputString = System.Console.ReadLine(); 
      enumParseResult = Enum.TryParse<T>(userInputString, out resultInputType); 
     } 

     return resultInputType; 
    } 

uso:

public enum myEnum { val1, val2 } 

myEnum enumValue = getEnumStringEnumType<myEnum>(); 
+0

Obtengo el mismo erroe: el tipo 'T' debe ser un tipo de valor que no admite nulos para usarlo como parámetro 'TEnum' en el tipo genérico o método 'System.Enum.TryParse (string, out TEnum); – Rami

+0

siga el código actualizado (agregué donde T: struct, new()). y mire la muestra de uso – eyossi

+0

-1: su código no se compila por tres razones. – Virtlink

1

Hace mucho tiempo en Visual Studio 2005 era, hice mi propio método para TryParse en Enum. Recientemente descubrí la implementación de 2008 y no estoy satisfecho con su carácter restrictivo, especialmente considerando que es un método TRY PARSE; lo que significa que un programador está probando una entrada!

En general, yo prefiero usar métodos que confían en el programador para saber lo que está haciendo :)

Mi aplicación es el siguiente:

public static bool EnumTryParse<T>(string input, out T theEnum) 
{ 
    foreach (string en in Enum.GetNames(typeof(T))) 
    { 
     if (en.Equals(input, StringComparison.CurrentCultureIgnoreCase)) 
     { 
      theEnum = (T)Enum.Parse(typeof(T), input, true); 
      return true; 
     } 
    } 

    theEnum = default(T); 
    return false; 
} 

La falta de un donde T: struct pone la confianza en manos del desarrollador, pero te permite compilar enum genéricos desconocidos.

Como alternativa, puede crear un método de bucle en Enum.GetValues ​​si desea hacer una comparación de números enteros al convertir a su enumeración especificada.

Espero que esto ayude.

Cuestiones relacionadas