所有枚举必须在其声明中使用以下类型之一:
byte、sbyte、short、ushort、int、uint、long 或 ulong。这是您指定类型的方式:
enum MyEnum3 : long {
Value1 = 5L,
Value2 = 9L,
Value3 = long.MaxValue
}
如果不指定类型,则默认为int。
很遗憾,您不能将char 指定为基础类型。您可以将该“扩展”创建为自定义属性:
[AttributeUsage(AttributeTargets.Enum)]
public class CharAttribute : Attribute { }
[Char] enum MyEnum2 {
Value1 = 'a',
Value2 = 'b',
Value3 = 'c'
}
然后有一个这样的类:
public static class EnumEx {
public static Type GetUnderlyingType(Type enumType) {
if (!enumType.IsEnum) throw new ArgumentException();
if (enumType.GetCustomAttributes(typeof(CharAttribute), false).Length > 0) {
return typeof(char);
}
return Enum.GetUnderlyingType(enumType);
}
public static object ConvertToUnderlyingType(object enumValue) {
return Convert.ChangeType(enumValue,
GetUnderlyingType(enumValue.GetType()));
}
}
(顺便说一句,Enum.GetUnderlyingType 方法似乎是您正在寻找的方法,但它永远不会返回 char,因为您不能在该语言中使用 char 枚举。)
这将让您了解 char 枚举的扩展概念:
var value3 = EnumEx.ConvertToUnderlyingType(MyEnum2.Value3);
Console.WriteLine(value3);
这会将c 打印到控制台。
注意底层类型和 char 枚举的值,理想情况下它们应该适合 char 以避免转换失败(溢出)。安全类型为 16 位宽(就像 char)或更少:byte、sbyte、short 或 ushort。如果枚举中的值可以在不损失精度的情况下转换为 16 位字符(就像上面的示例中一样),则其他类型也可以。
使用默认 (int) 基础类型和 char 文字作为枚举值(可隐式转换为 int)就足够了。
更新:
您可以在 F# 中声明一个字符枚举:
namespace Drawing
type Color =
| Red = 'r'
| Green = 'g'
| Blue = 'b'
在 C# 中,你可以这样使用它:
Console.WriteLine(Enum.GetUnderlyingType(typeof(Color)));
它会打印System.Char。
但是...如果您尝试使用它的值,C# 会报错。这个:
Console.WriteLine(Color.Red.ToString());
给出编译器错误:
错误 CS0570:该语言不支持“Drawing.Color.Red”
在 VB.NET 中没有编译错误,但是来自Enum.GetName 的运行时错误。似乎运行时不准备处理 char 枚举。这是该方法的摘录(来自 Reflector):
if (((!type.IsEnum && (type != intType)) && ((type != typeof(short)) && (type != typeof(ushort)))) && (((type != typeof(byte)) && (type != typeof(sbyte))) && (((type != typeof(uint)) && (type != typeof(long))) && (type != typeof(ulong)))))
{
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
}
它不仅检查类型是枚举,而且检查它是否是上述基础类型之一(char 不是一个选项)。 所以你真的不应该在 F# 中创建字符枚举。你可以使用我描述的“扩展”方法。