我是一个简短的枚举:
public enum EnumType : short
{
Value1 = 1,
Value2 = 2
}
然后我有一个看起来像这样的实用工具方法:
public static class EnumUtilities
{
public static IEnumerable<Tuple<TEnum, TBase>> GetTuples<TEnum, TBase>()
where TEnum : struct, TBase
{
return GetValues<TEnum>().Select(x => new Tuple<TEnum, TBase>(x, x));
}
public static IEnumerable<T> GetValues<T>() where T : struct
{
return Enum.GetValues(typeof(T)).Cast<T>();
}
}
当我尝试调用它时,我收到一个编译错误,说“Type EnumType必须可以转换为'short',以便在泛型方法'IEnumerable&gt; GetTuples()'中使用它作为参数'TEnum'
我很难理解,当定义为“短”时,EnumType不能转换为'short'。我也不理解以下编译方式,但上面的例子没有。任何帮助表示赞赏!
var enumType = EnumType.Value1;
var value1 = (short)enumType;
答案 0 :(得分:4)
问题的原因在于您编写的GetTuples<,>()
泛型方法约束
TEnum: struct, TBase
这意味着TEnum
应该来自TBase
的派生类型。我想你试图或多或少地称之为:EnumUtilities.GetTuples<EnumType, short>()
。 问题是EnumType
不是来自short
。
你宣布它的方式:
public enum EnumType: short
{ ... }
表示只应将short
用于此枚举作为表示其枚举成员的基础类型。所有枚举类型都派生自Enum
类,因此调用GetTuples<EnumType, short>
将无法使用您提供的代码进行编译,但GetTuples<EnumType, Enum>
将进行编译。
这就是为什么您的样本无法按预期工作的原因。
您可以通过删除继承约束并在运行时检查基础类型来修复GetTuples<,>()
方法:
public static IEnumerable<Tuple<TEnum, TBase>> GetTuples<TEnum, TBase>()
where TEnum : struct, IConvertible
{
Type tEnumType = typeof(TEnum);
if (!tEnumType.IsEnum || Enum.GetUnderlyingType(tEnumType) != typeof(TBase))
{
throw new ArgumentException("Invalid type specified.");
}
return GetValues<TEnum>().Select(x => new Tuple<TEnum, TBase>(x, (TBase)Convert.ChangeType(x, typeof(TBase))));
}
现在你应该可以调用EnumUtilities.GetTuples<EnumType, short>();
并且它应该正确编译。
此解决方案的缺点是运行时检查的效率低于使用编译时约束。
答案 1 :(得分:0)
您的EnumType继承自short,默认情况下是Enum,因此将EnumType值强制显示为short,而使用它时工作正常。另一种方法是在初始化时将值转换为short,如下所示。
public enum EnumType : short
{
Value1 = (short)1,
Value2 = (short)2
}
在这种情况下,使用时不需要施放。
答案 2 :(得分:0)
试试这个
public static class EnumUtilities
{
public static IEnumerable<Tuple<TEnum, object>> GetTuples<TEnum>() where TEnum : struct, IConvertible
{
if (!typeof(TEnum).IsEnum)
throw new Exception("wrong!");
return GetValues<TEnum>().Select(x => new Tuple<TEnum, object>(x, Convert.ChangeType(x, x.GetTypeCode())));
}
public static IEnumerable<T> GetValues<T>() where T : struct, IConvertible
{
if (!typeof(T).IsEnum)
throw new Exception("wrong!");
return Enum.GetValues(typeof(T)).Cast<T>();
}
}