提问者:小点点

枚举。GetName()作为常量属性


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

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

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

它工作得很好。

但我试图更好地保护它,因为这个特定的Enum比其他所有Enum都更重要,如果我不小心更改了字符串值,这将是不好的,所以我尝试让它变成这样的常量。

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

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

但是Visual Studio 2013抛出一个错误,指出“无法解析符号GetName”。我知道当它没有标记为“const”时它会起作用。

所以这就引出了两个问题?为什么它会丢失对GetName枚举的引用?(经过一番研究,我怀疑这与GetName是一个方法而不是Enum类的属性有关,但错误消息对我来说毫无意义)

最后,有没有办法将 MyEnum.Name 的名称读取到我正在做的之外的常量字符串中?


共3个答案

匿名用户

只需使其只读:

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);

< code>nameof之所以有效,是因为这里您没有调用任意方法,而是使用编译器功能来访问类型的名称。

匿名用户

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

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

匿名用户

它甚至可能在运行时不知道:

来自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和更高版本中,您可以对常量使用< code>nameof:

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