[英]Cast Int to Generic Nullable Enum in C#
我想使用一个泛型函数将int值转换为可为空的枚举。 我认为这会很容易,尤其是对于枚举/整数转换的所有SO。 我发现的最接近的问题是这个问题,但不幸的是,它不处理可为空的枚举。 这个问题解决了Nullable枚举转换问题,但不是泛型。
这是我要执行的操作的简化示例:
public enum SouthParkCharacters
{
Stan = 0,
Kyle = 1,
Eric = 2,
Kenny = 3
}
public static T CastNullableEnum<T>(int value)
{
return (T)(object)((int?)value).Value;
}
public static T SomeFunction<T>(this int anyEnumValue)
{
SouthParkCharacters? spc = SouthParkCharacters.Kenny;
spc = CastNullableEnum<SouthParkCharacters>(3); //I am working!
spc = CastNullableEnum<SouthParkCharacters?>(3); //Raise error Specified cast is not valid.
//This function will be public so I won't have control over the T
T finalValue = CastNullableEnum<T>(anyEnumValue); //Raise error Specified cast is not valid.
return finalValue;
}
如您在上一个函数中所见,对非空枚举的强制转换正在工作。 问题是我希望能够从另一个泛型函数调用CastNullableEnum,该泛型函数可以使用可为空的枚举作为泛型类型。
我知道您可以将通用类型作为可为空的通用CastNullableEnum<T?>
传递,但是我们可以做相反的操作(即,将可为空的基础类型传递给通用函数)吗?
如果无法做到这一点,那么我猜解决方案将是找到在CastNullableEnum函数中强制转换枚举值的正确方法。
我可能看错了这个问题,购买可以从nullable中获取基础类型,并使用Enum.Parse
而不是直接Enum.Parse
。
public T CastNullableEnum<T>(int value)
{
var enumType = Nullable.GetUnderlyingType(typeof(T));
if (Enum.IsDefined(enumType, value))
{
return (T)(object)Enum.Parse(enumType, value.ToString());
}
return default(T);
}
var test1 = CastNullableEnum<SouthParkCharacters?>(3);
//returns Kenny
var test2 = CastNullableEnum<SouthParkCharacters?>(9);
// returns null
有趣的问题。 此代码的问题是将整数强制转换为可为空的枚举,这是不可能的。
SouthParkCharacters? enumValue = (SouthParkCharacters?)int.MaxValue;
if (enumValue.HasValue)
{
Console.WriteLine("it still has value");
}
上面的代码正在运行,结果enumValue仍然为HasValue。
但是无论如何,如果您在编译后看一下C#代码,它将是这样的:
public static T CastNullableEnum<T>(int value)
{
Type type = typeof(T);
return (T)((object)value);
}
public static T SomeFunction<T>(int anyEnumValue)
{
Program.SouthParkCharacters? spc = new Program.SouthParkCharacters?(Program.SouthParkCharacters.Kenny);
spc = new Program.SouthParkCharacters?(Program.CastNullableEnum<Program.SouthParkCharacters>(new int?(3)));
spc = Program.CastNullableEnum<Program.SouthParkCharacters?>(new int?(3));
return Program.CastNullableEnum<T>(new int?(anyEnumValue));
}
现在,请注意
spc = new Program.SouthParkCharacters?(Program.CastNullableEnum<Program.SouthParkCharacters>(new int?(3)));
那就是Unspecified Cast Exception的来源; 因为新的SouthParkCharacters?(int值)需要一个整数。
有趣的是,使用“即时”运行时不会遇到此问题。 有意思吧?
这将起作用:
public static T IntToEnum<T>(object value)
{
if (value == null)
return (T)value;
else if (typeof(T).IsEnum)
return (T)value;
else if (Nullable.GetUnderlyingType(typeof(T))?.IsEnum == true)
return (T)Enum.ToObject(Nullable.GetUnderlyingType(typeof(T)), (int)value);
throw new Exception(string.Format("Value cannot be converted from {0} to {1}", value.GetType().Name, typeof(T).Name));
}
可用于可为空和常规枚举
public enum Codes
{
A = 1,
B = 2,
C = 3
}
static void Main(string[] args)
{
Console.WriteLine(IntToEnum<Codes?>(1));
Console.WriteLine(IntToEnum<Codes?>(null));
Console.WriteLine(IntToEnum<Codes>(2));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.