2010-09-28 12 views
5

estoy escribiendo algunas funciones de enumeración, y tienen las siguientes:añadir restricciones para anulable Enum

public static T ConvertStringToEnumValue<T>(string valueToConvert, bool isCaseSensitive) 
{ 
    if (typeof(T).BaseType.FullName != "System.Enum" && typeof(T).BaseType.FullName != "System.ValueType") 
    { 
     throw new ArgumentException("Type must be of Enum and not " + typeof (T).BaseType.FullName); 
    } 

    if (String.IsNullOrWhiteSpace(valueToConvert)) 
     return (T)typeof(T).TypeInitializer.Invoke(null); 

    valueToConvert = valueToConvert.Replace(" ", "");    

    if (typeof(T).BaseType.FullName == "System.ValueType") 
    { 
     return (T)Enum.Parse(Nullable.GetUnderlyingType(typeof(T)), valueToConvert, !isCaseSensitive); 
    } 

    return (T)Enum.Parse(typeof(T), valueToConvert, !isCaseSensitive); 
} 

me llaman así:

EnumHelper.ConvertStringToEnumValue<Enums.Animals?>("Cat"); 

ahora quiero añadir restricciones a T a un Enum, como (que obtuve de Stackoverflow article): where T : struct, IConvertible pero estoy teniendo problemas ya que T necesita poder tomar enumeraciones que se pueden anular. El mensaje de error dice:

El tipo 'Enums.Animals?' debe ser un tipo de valor no anulable con el fin de utilizarlo como parámetro de 'T' en el tipo genérico o método

¿Hay una manera de hacer esto, o tengo que confiar sólo en la comprobación en tiempo de ejecución, que Tengo dentro del método?

¡Gracias a todos!

+0

¡NO DUPLICAR SUS PREGUNTAS! Tal como está, tu código es falso. Por favor refiérase a su pregunta anterior, por qué digo eso. – leppie

+1

@leppie: Aunque el código actual es falso, la parte de restricción no es - y es una pregunta separada. –

+0

@Jon Skeet: Creo firmemente en resolver un problema a la vez. Por la forma en que funciona el OP, se confundirá y, en última instancia, desperdiciará todo el tiempo de las personas que intentan ayudarlo. – leppie

Respuesta

9

No, no hay ninguna restricción que diga "T debe ser un tipo de valor, incluidos los tipos de valor que aceptan valores numéricos".

Una opción, sin embargo, sería dividir el método en que:

public static T ConvertStringToEnumValue<T>(...) where T : struct 
public static T? ConvertStringToNullableEnumValue<T>(...) where T : struct 

Aparte de cualquier otra cosa, la aplicación de cada método sería entonces más simple, también.

Por supuesto, no sabemos cómo va a utilizar este código, pero si va a llamarlo directamente desde métodos no genéricos, este sería mi enfoque sugerido.

Por supuesto, eso aún no va a evitar que alguien lo llame con T=int o algo así ... es posible que desee consultar Unconstrained Melody para obtener restricciones más rígidas.

1

Hay un truco que implica C++/CLI que permite limitaciones genéricas en los Enums. Escribe una clase abstracta base en C++/CLI con la restricción Enum. Haga referencia a la biblioteca en un proyecto C# e implemente la clase base.