我知道这听起来有点奇怪,但我想将 T?
的对象转换为 int?
。我想要这个的原因是 T
始终是一个枚举,而且我也知道这个枚举可以转换为 int。我正在为枚举创建一个通用包装类并找到 this "solution"将泛型类型限制为枚举类型。
我的代码目前看起来像这样:
public class EnumWrapper<T>
where T : struct, IConvertible
{
public EnumWrapper()
{
if (!typeof(T).IsEnum)
{
throw new ArgumentException("T must be an enumerated type");
}
}
public T? Enum { get; set; }
public int? EnumValue => (int?)Enum; // this won't compile
...
}
我知道在转换为值类型 ((int?)(object)Enum
) 之前转换为对象会欺骗编译器,但这在这里也有效吗?我怀疑 nullable 会干扰这一点。
所以我的问题是:实现这种通用行为的最佳方式是什么?
最佳答案
由于 T
是 IConvertible
,您可以使用 ToInt32()
方法避免转换和装箱:
public int? EnumValue => this.Enum?.ToInt32(CultureInfo.CurrentCulture.NumberFormat);
this.Enum?
将确保返回 null
以防实际值丢失。
此外,由于我们试图保留包装枚举的值类型语义,您需要将 EnumWrapper
从 class
更改为 struct
并使用扩展方法轻松包装值:
public struct EnumWrapper<T> where T : struct, IConvertible
{
public T? Enum { get; set; }
public int? EnumValue => this.Enum?.ToInt32(CultureInfo.CurrentCulture.NumberFormat);
}
public static class EnumWrapperExtension
{
public static EnumWrapper<T> Wrap<T>(this T data) where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
throw new ArgumentException("T must be an enumerated type");
return new EnumWrapper<T> { Enum = data };
}
}
用法:
public enum Color
{
Red = 1,
Green = 2,
}
var color = Color.Green;
var colorAsInt = color.Wrap().EnumValue;
参见 MSDN
关于c# - 将泛型但已知为可空枚举类型转换为可空 int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40375798/