c# - unity - ¿Cómo convertir un objeto arbitrario a enum?
enum.getname c# (2)
Tengo un objeto. Por lo general, es long
o string
, por lo que para simplificar el código supongamos eso.
Tengo que crear un método que intente convertir este objeto en una enumeración proporcionada. Asi que:
public object ToEnum(Type enumType, object value)
{
if(enumType.IsEnum)
{
if(Enum.IsDefined(enumType, value))
{
var val = Enum.Parse(enumType, (string)value);
return val;
}
}
return null;
}
Con cuerdas, funciona bien. Con números, causa problemas, porque un tipo subyacente por defecto para enum es int
, no long
e IsDefined
arroja una ArgumentException
.
Por supuesto que puedo hacer muchos controles, conversiones o intentos de captura.
Lo que quiero es tener un código limpio y pequeño para eso. ¿Alguna idea de cómo hacerlo legible y simple?
Me parece que en realidad solo quieres manejar tres casos:
- La entrada ya es del tipo correcto
- Instrumentos de cuerda
- Enteros en varios tipos
Creo que esto hará lo que quieras para una entrada válida:
public object ToEnum(Type enumType, object value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (enumType == null)
{
throw new ArgumentNullException("type");
}
if (!enumType.IsEnum)
{
return false;
}
string valueString = value as string;
if (valueString != null)
{
return Enum.IsDefined(enumType, value) ? Enum.Parse(enumType, valueString) : null;
}
if (value.GetType() == enumType)
{
return value;
}
// This appears to handle longs etc
return Enum.ToObject(enumType, value);
}
Sin embargo, devolverá un valor del tipo correcto incluso para valores indefinidos. Si no quiere eso, cambie la última parte a:
object candidate = Enum.ToObject(enumType, value);
return Enum.IsDefined(enumType, candidate) ? candidate : null;
Además, esto arrojará una excepción si pasa un número de punto flotante o algo así. Si no quieres ese comportamiento, necesitarás tener un conjunto de todos los tipos que deseas aceptar, y contrasta con eso primero.
Prueba esto
public object ToEnum<T>(object value)
{
var type = typeof(T);
if (type.IsEnum)
{
int numberVal;
if (!int.TryParse(value.ToString(), out numberVal) && value.GetType() != typeof(string))
{
return null;
}
value = numberVal;
if (Enum.IsDefined(type, value))
{
T result = (T)Enum.Parse(type, value.ToString());
return result;
}
}
return null;
}