He leído algunas publicaciones SO y parece que falta la operación más básica.
public enum LoggingLevel
{
Off = 0,
Error = 1,
Warning = 2,
Info = 3,
Debug = 4,
Trace = 5
};
if (s == "LogLevel")
{
_log.LogLevel = (LoggingLevel)Convert.ToInt32("78");
_log.LogLevel = (LoggingLevel)Enum.Parse(typeof(LoggingLevel), "78");
_log.WriteDebug(_log.LogLevel.ToString());
}
Esto no causa excepciones, es feliz de almacenar 78
. ¿Hay alguna manera de validar un valor que entra en una enumeración?
Respuestas:
Echa un vistazo a Enum.IsDefined
Uso:
Este es el ejemplo de esa página:
El ejemplo muestra el siguiente resultado:
fuente
LoggingLevel
use como almacenamiento, luego preséntelo como unLoggingLevel
valor de enumeración.IsDefined
no funciona para los miembros de enumeración bitwised.Las soluciones anteriores no abordan
[Flags]
situaciones.Mi solución a continuación puede tener algunos problemas de rendimiento (estoy seguro de que uno podría optimizar de varias maneras) pero esencialmente siempre probará si un valor de enumeración es válido o no .
Se basa en tres supuestos:
int
, absolutamente nada más-
Llamar
ToString()
a una enumeración devuelve elint
valor si no se coincide ninguna enumeración (marca o no). Si un valor de enumeración permitido coincide, imprimirá el nombre de la (s) coincidencia (es).Entonces:
Con estas dos reglas en mente, podemos suponer que si .NET Framework hace su trabajo correctamente, cualquier llamada a un
ToString()
método de enumeración válido dará como resultado algo que tenga un carácter alfabético como primer carácter:Uno podría llamarlo un "hack", pero las ventajas son que al confiar en la propia implementación de Microsoft
Enum
y en los estándares de C #, no está confiando en su propio código o verificación potencialmente defectuoso. En situaciones donde el rendimiento no es excepcionalmente crítico, ¡esto ahorrará muchasswitch
declaraciones desagradables u otras comprobaciones!Editar
Gracias a @ChaseMedallion por señalar que mi implementación original no admitía valores negativos. Esto ha sido remediado y se proporcionaron pruebas.
Y las pruebas para respaldarlo:
fuente
[Flags]
tienen valores enteros razonables.La respuesta canónica sería
Enum.IsDefined
, pero eso es a: un poco lento si se usa en un ciclo cerrado, yb: no es útil para las[Flags]
enumeraciones.Personalmente, dejaría de preocuparme por eso, y de manera
switch
apropiada, recordando:default:
(o tenga un vacíodefault:
explicando por qué)default:
Al igual que:
fuente
Utilizar:
fuente
Use Enum.IsDefined .
fuente
Para tratar con
[Flags]
usted, también puede usar esta solución de C # Cookbook :Primero, agregue un nuevo
ALL
valor a su enumeración:Luego, verifique si el valor está en
ALL
:fuente
Una forma de hacerlo sería confiar en la conversión de conversión de enum a cadena. Al convertir int en un tipo Enum, int se convierte en un valor enum correspondiente o la enum resultante solo contiene int como valor si el valor enum no está definido para int.
No probado para ningún caso de borde.
fuente
Como dijeron los demás,
Enum.IsDefined
regresafalse
incluso si tiene una combinación válida de banderas de bits para una enumeración decorada con elFlagsAttribute
.Lamentablemente, la única forma de crear un método que devuelva verdadero para marcas de bits válidas es un poco largo:
Es posible que desee almacenar en caché los resultados de
GetCustomAttribute
un diccionario:Tenga en cuenta que el código anterior usa la nueva
Enum
restricciónT
que solo está disponible desde C # 7.3. Necesita pasar unobject value
en versiones anteriores y recurrirGetType()
a él.fuente