如何确定表示类型的枚举值?

考虑以下两个枚举:

enum MyEnum1 {
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

enum MyEnum2 {
     Value1 = 'a',
     Value2 = 'b',
     Value3 = 'c'
}

我可以通过显式转换, ((int)MyEnum1.Value2) == 2((char)MyEnum2.Value2) == 'b'检索由这些枚举值表示的物理值,但是如果我想获取char表达式还是int表示,而不先知道要转换的类型?

是否有可能在没有转换的情况下获得枚举的基础值,或者是否至少在编程上可以确定基础值的正确类型?


这两个枚举的基础值是int 。 你只是在第二种情况下使用了从charint的隐式转换这一事实。

例如,如果您查看Reflector中的第二个枚举,则会看到如下所示的内容:

internal enum MyEnum2
{
    Value1 = 0x61,
    Value2 = 0x62,
    Value3 = 0x63
}

编辑:如果你想要一个不同的基础类型,你必须指定它,例如

public enum Foo : long
{
}

但是,只有bytesbyteshortushortintuintlongulong才是有效的基础枚举类型。


所有枚举必须在其声明中使用以下类型之一: bytesbyteshortushortintuintlongulong 。 这是你如何指定一个类型:

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是, Enum.GetUnderlyingType方法似乎是您正在寻找的方法,但它永远不会返回char因为您不能在该语言中使用字符枚举。)

这将允许你得到你的扩展char枚举的概念:

var value3 = EnumEx.ConvertToUnderlyingType(MyEnum2.Value3);
Console.WriteLine(value3);

这会将c打印到控制台。

注意char枚举的基本类型和值,理想情况下它们应该适合char以避免转换失败(溢出)。 安全类型是16位宽(与char类似)或更少: bytesbyteshortushort 。 如果enum中的值可以转换为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");
  }

它不仅检查该类型是枚举,而且它也是前述的基础类型之一(对于这种类型,字符不是选项)。 所以你真的不应该在F#中创建char枚举。 你可以使用我描述的“扩展”方法。


枚举在幕后只是一个int类型。 您可以将其更改为long,byte和其他一些字符,但它们必须是数字。 Char只是在这里工作,因为它可以改变为int。 所以,对不起,我不认为这是可能的。

链接地址: http://www.djcxy.com/p/48121.html

上一篇: How to determine the represented type of enum value?

下一篇: Display a view from another controller in ASP.NET MVC