正确识别具有相同基础值的枚举

时间:2017-04-05 10:16:16

标签: c# enums

假设我定义了enum,其中有几个成员具有相同的基础值:

enum Number
{
  One = 1,
  Eins = 1,
  Uno = 1
}

根据MSDN documentation

  

如果多个枚举成员具有相同的基础值,并且您尝试根据其基础值检索枚举成员名称的字符串表示形式,则您的代码不应对该方法将返回的名称做出任何假设。

例如,

var number = Number.One;
Console.WriteLine(number);

给我以下输出:

  

一型

打印所有枚举成员,

Console.WriteLine($"{Number.One} {Number.Eins} {Number.Uno}");

产生以下输出:

  

Eins Eins Eins

但是,取每个成员的nameof

Console.WriteLine($"{nameof(Number.One)} {nameof(Number.Eins)} {nameof(Number.Uno)}");

给出以下结果:

  

One Eins Uno

显然,enum成员 是可分离的。我可以利用这种分离,即是否有任何方式我可以将特定的Number成员分配给变量,并始终在每次返回时返回相同的成员访问变量?

3 个答案:

答案 0 :(得分:7)

  

显然,System.getProperties().setProperty("https.protocols", "TLSv1.1");成员 可分离

嗯,这并不完全正确......它们只能在编译时分离。

您看,enum实际上是在编译时计算的表达式。这是一个不变的表达。这可以通过将nameof表达式分配给nameof

来证明
const

它编译。<​​/ p>

另一方面,尝试使用字符串插值获取枚举值的字符串表示形式,在运行时进行评估,因此无法编译:

const string a = nameof(Number.One);

在运行时,枚举案例是不可分的,所以答案是:

  

有没有什么办法可以为变量分配一个特定的Number成员,并且每当访问该变量时都会返回相同的成员?

是&#34; no&#34;。

答案 1 :(得分:2)

我看到总是返回预期枚举名称的唯一可能性是在您的第一个基础类型旁边创建第二个enum并使用相同的值,但将成员限制为您期望的成员(并确保没有共享值)。然后你可以从一个转换到另一个并在你重构的代码中使用新的枚举,它依赖于特定/期望的成员。

<强>的someMethod

Console.WriteLine("{0:G}", (KnownNumber)Number.Eins); // > One
Console.WriteLine("{0:G}", (KnownNumber)Number.Uno); // > One
Console.WriteLine("{0:G}", (KnownNumber)Number.One); // > One

Enums.cs

public enum Number
{
  One = 1,
  Eins = 1,
  Uno = 1
}

public enum KnownNumber
{
  One = 1,
  Two = 2,
  Three = 3
}

Fiddle

答案 2 :(得分:0)

我写了一些应该让它发挥作用的东西

public static class NumberExtension
{
    private static Dictionary<int, string> pointers = new Dictionary<int, string>();
    public static unsafe void SetValue(this Number source, string value)
    {
        if (pointers.ContainsKey((int)&source))
            pointers[(int)&source] = value;
        else
            pointers.Add((int)&source, value);
    }
    public static unsafe string GetValue(this Number source)
    {
        if (pointers.ContainsKey((int)&source))
            return pointers[(int)&source];
        return source.ToString();
    }
}

使用:

    Number num = default(Number);
    num.SetValue(nameof(Number.Uno));
    Console.WriteLine(num.GetValue());

然而,它看起来像是一种“黑客”。我不推荐它。如果你寻找更好的解决方案会更好。