可能将System.InvalidCastException强制将Enum强制转换为int吗?

时间:2019-01-07 20:44:19

标签: c# resharper compiler-warnings

我有以下代码段:

internal static class Program
{
    private enum MyEnum
    {
        MyVal = 2,
    }
    private enum AlsoMyEnum
    {
        AlsoMyVal = 2,
    }
    private static class Thing
    {
        public static object DoThing(object objectIn) =>
            objectIn is Enum ? (int)objectIn : objectIn;
    }
    [STAThread]
    private static void Main(string[] args)
    {
        var objectOut = Thing.DoThing(MyEnum.MyVal);
        var objectOut2 = Thing.DoThing(AlsoMyEnum.AlsoMyVal);
        var @false = MyEnum.MyVal.GetType() == AlsoMyEnum.AlsoMyVal.GetType();
        var @true = objectOut.GetType() == objectOut2.GetType();
    }
}

ReSharper抱怨“(int)objectIn”是“可能的'System.InvalidCastException'”。

根据我的理解,此代码很好(因此,我应该禁止显示警告)-如果某物是枚举,则将其强制转换为int应该是有效的。但是,我想检查一下-我错过了什么吗?

警告是否正确?还是有其他写方法可以避免警告,同时仍将int放入parameter.Value中?

编辑

感谢@InBetween指出警告实际上是正确的。为了修复代码,应改用以下代码:

        public static object DoThing(object objectIn) => objectIn is Enum
            ? Convert.ChangeType(objectIn, Enum.GetUnderlyingType(objectIn.GetType()))
            : objectIn;

3 个答案:

答案 0 :(得分:1)

装箱的枚举只能转换为其基础类型。这将失败:

enum LongEnum: long
{
    Woops
}

object o = LongEnum.Woops;
var i = (int)o;

这是由于更通用的规则所致:任何装箱的值类型只能取消装箱至其类型:

object o = 1; //boxed int
var s = (short)o; //fails

答案 1 :(得分:0)

假设您正在使用C#7,则可以将模式匹配的结果分配给变量。

如果您的枚举类似:

public enum TestEnum
{
    A = 1,
    B = 2,
    C = 3
}

然后您可以使用

处理它
if (param.Value is TestEnum enumValue)
{
    parameter.Value = (int)enumValue;
}

尽管您不能将System.Enum强制转换为int,所以如果您的示例反映了您的实际代码,则它实际上不会编译。

答案 2 :(得分:-1)

您可以尝试下面给出的答案中提到的代码 C# Iterating through an enum? (Indexing a System.Array)

这里的主要目的是要知道每个枚举值将包含两个部分-名称和值。值可以转换为整数。

Enum.GetValues返回该枚举中所有值的数组。如果只希望这样做,则仅需要第一行代码。

    public enum MyEnum
    {
        First,
        Second,
        Third
    }

    private void EnumValues()
    {

        Array values = Enum.GetValues(typeof(MyEnum));

        foreach (MyEnum val in values)
        {
            //// To print name and value in enum
            Console.WriteLine(String.Format("{0}: {1}", Enum.GetName(typeof(MyEnum), val), val));


            //// To get only value
            int i = (int)val;
        }
    }

希望这会有所帮助。