variable - tipos de datos en c# visual studio
Conversión de un entero a un tipo de enumeración en caja solo conocido en tiempo de ejecución (2)
Creo que el método Enum.ToObject
hará lo que quieras.
Type type= typeof(Foo);
object o1 = Enum.ToObject(type,GetValue());
Imagina que tenemos una enumeración:
enum Foo { A=1,B=2,C=3 }
Si se conoce el tipo en tiempo de compilación, se puede usar un molde directo para cambiar entre el tipo enum y el tipo subyacente (generalmente int
):
static int GetValue() { return 2; }
...
Foo foo = (Foo)GetValue(); // becomes Foo.B
Y boxeo esto da una caja de tipo Foo
:
object o1 = foo;
Console.WriteLine(o1.GetType().Name); // writes Foo
(y de hecho, puede boxear como Foo
y unbox como int
, o box como int
y unbox como Foo
bastante felizmente)
Sin embargo (el problema); si el tipo enum solo se conoce en el tiempo de ejecución, las cosas son ... más complicadas. Obviamente, es trivial incluirlo como int
, pero ¿puedo boxearlo como Foo
? (Idealmente sin usar genéricos y MakeGenericMethod
, que sería feo). Convert.ChangeType
arroja una excepción. ToString
y Enum.Parse
funciona, pero es terriblemente ineficiente.
Podría mirar los valores definidos ( Enum.GetValues
o Type.GetFields
), pero eso es muy difícil para [Flags]
, e incluso sin requeriría volver primero al tipo subyacente (que no es tan difícil, afortunadamente) .
Pero; ¿Hay una forma más directa de obtener un valor del tipo subyacente correcto en un recuadro del tipo enum, donde el tipo solo se conoce en el tiempo de ejecución?
Solo quería agregar algo a la respuesta de @ aaronb : tuve que hacer esto mismo para un código de asignación automática y descubrí que tenía que hacer varias comprobaciones para que el código funcionara para tipos arbitrarios. En particular, los valores nulos y las enumeraciones que se pueden anotar te darán dolores de cabeza.
El código más infalible que tengo en este momento es este:
static object CastBoxedValue(object value, Type destType)
{
if (value == null)
return value;
Type enumType = GetEnumType(destType);
if (enumType != null)
return Enum.ToObject(enumType, value);
return value;
}
private static Type GetEnumType(Type type)
{
if (type.IsEnum)
return type;
if (type.IsGenericType)
{
var genericDef = type.GetGenericTypeDefinition();
if (genericDef == typeof(Nullable<>))
{
var genericArgs = type.GetGenericArguments();
return (genericArgs[0].IsEnum) ? genericArgs[0] : null;
}
}
return null;
}
Si nunca puedes tener un tipo que admite nulos, simplemente ignóralo. :)