我已经在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字符串?
答案 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);