【问题标题】:Cannot convert type 'System.Enum' to int无法将类型“System.Enum”转换为 int
【发布时间】:2010-12-11 05:50:20
【问题描述】:

(好吧,我就在这里暴露我的无知,请温柔)

背景

我有一个看起来(有点)像这样的方法:

public void AddLink(Enum enumVal)
{
     string identifier = m_EnumInterpreter(enumVal);
     AddLink(identifier);
}

EnumInterpreter 是一个 Func 在创建父类时传入的。

我使用 Enum 是因为在这个级别上它“不关我的事”——我不在乎它是哪个特定的枚举。调用代码只是使用(生成的)枚举来避免魔术字符串。

问题

如果 EnumInterpreter 发回一个空字符串,我想用 enumVal 的实际值抛出一个异常。我以为我只能强制转换为 int,但编译器不会拥有它。我究竟做错了什么? (请不要说“一切”)。

【问题讨论】:

标签: c# .net enums casting


【解决方案1】:

System.Enum 不能直接转换为 Integer,但它确实显式实现了 IConvertible,这意味着您可以使用以下内容:

public void AddLink(Enum enumVal)
{
    string identifier = m_EnumInterpreter(Convert.ToInt32(enumVal));
    AddLink(identifier);
}

请记住,如果您的 Enum 实际使用的不是整数(例如浮点数),您将在转换时丢失非整数数据。或者显然将 Convert 调用替换为您要转换的任何内容(如果已知)

【讨论】:

【解决方案2】:

不,您无法将其转换为 int,因为 System.Enum 不是枚举,它只是枚举的基类。

编辑:

你可以得到如下的值,但是很丑:

int intVar = (int)enuYourEnum.GetType().GetField("value__").GetValue(objYourEnum);

【讨论】:

  • 请注意,如果int 不是枚举的基础类型,这将失败。
  • 好吧,我必须承认它不是,它是一个 uint,但我想我找到了适合我的东西......
  • GetField() 是否需要 BindingAttributes,因为 value__ 是私有的?
【解决方案3】:

试试这个..

m_EnumInterpreter((int) (object) enumVal);

【讨论】:

    【解决方案4】:

    这里有各种各样的东西:

    1) Ryan 的答案看起来不错,但是...我宁愿将 Enum 传递给 enum 解释器,这样您就可以在那里完成整个 Convert.To...。如果您知道您只使用基于整数的枚举,那么 Convert.ToInt32() 就可以了。否则,您可能需要使用反射或尝试/捕获其他转换来添加。

    2) 您也可以考虑使用 Enum 类的成员,例如 .GetName()、.GetValue() 等,因为它们直接处理定义的名称和值,与枚举类型无关。

    3) 从技术上讲,我不会在枚举解释器之外抛出异常。如果该条件通常为真,则从枚举解释器内部抛出异常,以便该类的所有使用都将受益于验证。或者你可能最终会重复代码。

    4) 从变量命名来看,您似乎有 C++/MFC 背景。您可能想了解 C# 风格的命名约定,它会在使用/阅读其他人的代码和库时让您的生活更加轻松。查看 MS 的 StyleCop 以获得一个很好的插件来帮助命名。

    【讨论】:

    • 1) 它实际上是 uint,但没有任何规定。 2) EnumInterpreter 的当前(唯一)实现确实使用 Enum.GetName(),GetValue() 不存在。 3)鉴于 EnumInterpreter 可以从外部传入/覆盖,我不想太信任。 4)我与具有这种背景的人一起工作,他们在我之前决定命名约定,但我会看看你的建议。
    • 是的,对不起,它实际上是 .GetValues()
    【解决方案5】:

    我不知道是否将其包含在我的问题中或作为答案。问题是它不是答案,而是对我有用的答案。

    我在尝试其他方法时偶然发现,如果我只是将它放在字符串的末尾,我会得到我想要的:

    throw new Exception("EnumInterpreter returns empty string for enumVal=" + enumVal);
    //EnumInterpreter returns empty string for enumVal=3720116125
    

    我实际上在我的问题中简化为 int,真正的数据类型是 uint(在这个特定的例子中)。幸运的是,鉴于我实际上只想要字符串,我不必担心。

    我不确定其他三个答案中哪一个是“正确的”,所以投票吧...

    【讨论】:

      【解决方案6】:

      我知道这可能不是您确切问题的解决方案,但我只想发布我如何针对我正在使用的特定 API 解决此问题。

      int result = (int) (ActualEnumType) MethodThatReturnsSystemEnumType( arg1, arg2 );
      

      希望这对某人有所帮助。双重投射 FTW。

      【讨论】:

        【解决方案7】:

        为什么不将枚举解析为字符串并返回实际的枚举值?

        public enum MyEnum { Flower = 1, Tree = 2, Animal = 3 };
        
        string name = MyEnum.Flower.ToString(); // returns "Flower"
        

        我认为.ToString() 已被弃用,我不确定新的方法。我会认为实际的枚举表示会比 int 更有用?

        【讨论】:

        • 因为在相关代码的上下文中,我无权访问枚举。
        • 实际上只弃用了 .ToString() 的一个重载 - 在这方面,智能感知实际上非常具有误导性。
        • "为什么不将枚举解析为字符串并返回实际的枚举值?" - 底层 Int32 是实际的枚举值。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多