【问题标题】:Why does Enum.ToString() not return the correct enum name?为什么 Enum.ToString() 不返回正确的枚举名称?
【发布时间】:2014-05-08 19:35:09
【问题描述】:

我正在使用具有枚举的外部库。这个枚举的一些成员,当你对它们调用ToString() 时,会返回枚举中不同成员的名称。

Console.WriteLine("TOKEN_RIGHT = {0}", Tokens.TOKEN_RIGHT.ToString());  //prints TOKEN_OUTER
Console.WriteLine("TOKEN_FROM = {0}", Tokens.TOKEN_FROM.ToString());  //prints TOKEN_FROM
Console.WriteLine("TOKEN_OUTER = {0}", Tokens.TOKEN_OUTER.ToString());  //prints TOKEN_FULL

我知道当两个枚举成员具有相同的数值时,你可以得到这样的行为,但我知道,通过反编译和在运行时检查值,枚举中的每个成员都有一个唯一的值。

这是枚举定义的 sn-p(由dotPeek 生成):

public enum Tokens
{

    TOKEN_OR = 134,
    TOKEN_AND = 135,
    TOKEN_NOT = 136,
    TOKEN_DOUBLECOLON = 137,
    TOKEN_ELSE = 138,
    TOKEN_WITH = 139,
    TOKEN_WITH_CHECK = 140,
    TOKEN_GRANT = 141,
    TOKEN_CREATE = 142,
    TOKEN_DENY = 143,
    TOKEN_DROP = 144,
    TOKEN_ADD = 145,
    TOKEN_SET = 146,
    TOKEN_REVOKE = 147,
    TOKEN_CROSS = 148,
    TOKEN_FULL = 149,
    TOKEN_INNER = 150,
    TOKEN_OUTER = 151,
    TOKEN_LEFT = 152,
    TOKEN_RIGHT = 153,
    TOKEN_UNION = 154,
    TOKEN_JOIN = 155,
    TOKEN_PIVOT = 156,
    TOKEN_UNPIVOT = 157,
    TOKEN_FROM = 242,
}

为什么会这样?是不是我做错了什么,或者这只是 .NET 中枚举的另一个有趣的怪癖?如果是后者,是否有解决方法?

(不管怎样,Tokens 是 .NET 中 Microsoft.SqlServer.Management.SqlParser.Parser 命名空间的一部分。)

【问题讨论】:

  • 如果设置断点,然后在“立即”窗口中计算 .ToString 表达式会怎样?
  • 这是一个完整的复制粘贴吗?额外的,最后在我看来不合适
  • 枚举列表中没有 TOKEN_FROM(我知道来自 sn-p 的代码),我在 dotnetfiddle 中对此进行了测试-> TOKEN_OUTER = TOKEN_OUTER
  • 我想您可能正在查看两个不同版本的程序集。您的代码(在设计时)可能引用了较新的版本(因为您可以使用 TOKEN_FROM 但是当您使用 dotPeek 检查 DLL 时,它不存在)但在运行时加载的程序集可能是具有不同的旧版本基础值因此名称不匹配。
  • 非常简单的方法来找出是否有重复你可以做:添加一个带有Tokens的switch语句,让VS为你生成switch case。然后编译。如果有重复,编译器不会让你编译。

标签: c# .net enums


【解决方案1】:

您正在查看程序集的两个不同版本。

您的代码(在设计/编译时)引用了较新的版本(因为您可以使用TOKEN_FROM,但是当您使用 dotPeek 检查 DLL 时,它不存在)。但是,在 runtime 加载的程序集是旧版本,具有不同的基础值,因此名称不匹配。

您必须调查您是如何引用不匹配的 DLL 的。可能是执行机器上安装的框架,也可能是同一个解决方案中的项目引用了不同的版本,也可能是其他原因(根据您提供的信息无法确定)。

一旦您解决了引用两个不同版本的原因并将其统一为一个程序集版本,Enum.ToString() 结果应该与您预期的一样。

【讨论】:

  • 快速说明一下,对于这个特定的 DLL,问题来自 Visual Studio 使用该 DLL(用于数据库项目),但我在项目的参考中引用了旧版本。跨度>
【解决方案2】:

我建议探测:

Console.WriteLine("TOKEN_RIGHT = {0}", Tokens.TOKEN_RIGHT.ToString("F"));

等等

【讨论】:

  • 请缩进您的代码,使其格式正确
猜你喜欢
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 2020-06-12
  • 2016-11-22
  • 1970-01-01
  • 2012-07-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多