尝试调用调用会导致“对象与目标类型不匹配”

时间:2014-06-10 02:29:10

标签: c# reflection enums

我试图对我在.net中定义的一系列枚举的使用进行一些考虑因素

    private static String GetSystemTranslatedField(Type enumtype, int? val) {
        if (val == null)
            return "";

        int value = (int)val;
        String tempstr;
        if (Enum.IsDefined(enumtype, value))
        {
            tempstr = (String) enumtype.GetMethod("ToString",Type.EmptyTypes).Invoke(val,null); 
            //equivalent to ((enumtype)val).ToString();
        }
    }

问题在于,当我试图运行它时,我会得到臭名昭着的System.Reflection.TargetException: Object does not match target type.

作为一个额外的问题,有没有办法改变我的方法的签名,以便只接受从Enum派生的类型?这不是一个大问题,但我对类型限制感到好奇,无法找到任何东西。

2 个答案:

答案 0 :(得分:1)

Enum is a class,因此您可以将其设置为方法签名的基础,并完全避免反射。尝试:

    private static String GetSystemTranslatedField(Enum enumtype, int? val) {
        if (!val.HasValue)
            return "";

        String tempstr;
        if (Enum.IsDefined(enumtype, val.Value))
        {
            tempstr = ((enumtype)val.Value).ToString(); 
        }

        ... // Rest of your code here
    }

请注意,我清理了你的方法,主要是化妆品。

答案 1 :(得分:1)

您正在尝试从ToString上的枚举类型调用Int32,这会导致Reflection API中出现异常。

如果您想获取与值相关的标识符,请使用Enum.GetName,这也适用于int(虽然文档似乎没有表明这一点):

if (Enum.IsDefined(enumtype, value))
{
    tempstr = Enum.GetName(enumType, value);
}

实际上,如果没有定义值,它将返回空字符串,因此如果也可以删除(取决于代码的其余部分):

tempstr = Enum.GetName(enumType, value);

C#不允许对Enum派生类型进行通用约束。它在理论层面上是可行的(它不被CLR禁止)但是它需要一些IL编织,Jon Skeet在他的Unconstrained Melody project中展示了它。