Enum.GetName()As Constant属性

时间:2016-03-03 13:30:28

标签: c# enums compiler-errors const constants

我已经在C#工作了大约8个月,所以请原谅我,如果这是愚蠢的......

我有一个枚举,我将在类中多次需要字符串值。所以我想使用Enum.GetName()将它设置为一个没有问题的字符串变量。我只是这样做......

private string MyEnumString = Enum.GetName(typeof(MyEnum), MyEnum.Name);

它运作得很好。

但是我试图保护它好一点,因为这个特殊的Enum比其他所有更重要,如果我不小心改变了字符串值,那就不好了所以我试着让它像这样的常量。

private const string MyEnumString = Enum.GetName(typeof(MyEnum), MyEnum.Name);

在我看来,这似乎很好,因为它应该在编译时都知道。

但Visual Studio 2013引发错误,指出“无法解析符号GetName”。我知道它没有标记为“const”时有效。

所以这引出了两个关于此的问题? 为什么它松散引用GetName枚举? (经过一些研究后我怀疑它与GetName是一个方法有关,而不是Enum类的属性,但错误信息对我来说没有意义)

最后是否有一种方法可以将MyEnum.Name的名称读取为除我正在做的之外的const字符串?

3 个答案:

答案 0 :(得分:2)

只需将其设为只读:

private readonly string MyEnumString = Enum.GetName(typeof(MyEnum), MyEnum.Name);

之后就无法改变。

您不能将调用方法的结果分配给常量; C#只是不允许它 - 编译器必须在编译时调用该方法,可能在它编译之前(并且它不仅必须生成IL,它还必须使用JIT编译器来编译那个IL)。

Enum.GetName(typeof(MyEnum), MyEnum.Name);正在调用方法,因此您无法将结果分配给常量。

[编辑]正如Jon Skeet在上面的评论中所说,如果使用C#6或更高版本(即VS2015或更高版本),您可以使用nameof

private const string MyEnumString = nameof(MyEnum.Name);

nameof有效,因为在这里你没有调用任意方法,而是使用编译器功能来访问类型的名称。

答案 1 :(得分:0)

您不能将方法的结果用作常量,因为方法评估只能在运行时进行。必须在编译时知道常量的值。为了使编译器能够评估该常量,它需要知道Enum.GetName的语义并在编译时执行它,这是不可能的

您可以将其标记为static readonly。这样,它将在声明它的每个类型中设置一次,并且在运行时不能再更改。

答案 2 :(得分:0)

运行时

可能甚至都不知道

来自MSDN

  

如果多个枚举成员具有相同的基础值,则GetName方法保证它将返回其中一个枚举成员的名称。但是,并不保证它始终会返回相同枚举成员的名称

(强调补充)

void Main()
{
    Console.WriteLine (Enum.GetName(typeof(Test),Test.One));
}

public enum Test
{
   Zero,
   One,
   Two,
   Uno = 1,
   Dos = 2,
}

我始终获得上述程序的输出Uno

原因是不知道是因为枚举被编译为基础。上面的调用基本上编译为Enum.GetName(typeof(Test), 1)GetName查找具有该值的成员以查找名称。它是如何做的显然是一个实现细节,可能无法产生一致的结果。

在C#6及更高版本中用于常量的内容为nameof

private const string MyEnumString = nameof(MyEnum.Name);