我已经在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 的名称读取到我正在做的之外的常量字符串中?
只需使其只读:
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);