使用类型变量转换为枚举

时间:2011-10-05 03:15:29

标签: c# reflection enums

我的部分软件使用反射。我遇到的问题是,虽然我可以获取属性的类型,但我无法使用PropertyInfo中的Type转换字符串值。这就是我在示例代码中使用t的原因。

以下代码演示了错误消息作为代码注释的问题。语法错误在t上。我该如何解决这个问题?感谢

class Program
{
    static void Main(string[] args)
    {
        Type t = typeof(Letters);

        Letters letter = "A".ToEnum<t>(); //-- Type or namespace expected.
    }
}

public enum Letters { A, B, C }

//-- This is a copy of the EmunHelper functions from our tools library.
public static class EnumExt
{
    public static T ToEnum<T>(this string @string)
    {
        int tryInt;
        if (Int32.TryParse(@string, out tryInt)) return tryInt.ToEnum<T>();
        return (T)Enum.Parse(typeof(T), @string);
    }
    public static T ToEnum<T>(this int @int)
    {
        return (T)Enum.ToObject(typeof(T), @int);
    }
}

解决方案:

以下情况有效,因为使用反射设置值时,将接受实际的枚举类型。 myObject.Letter = result不在哪里。

Type t = currentProperty.PropertyType;
Enum result = Enum.Parse(t, @string) as Enum;
ReflectionHelper.SetProperty(entity, "LetterPropertyName", result);

谢谢大家的帮助。

4 个答案:

答案 0 :(得分:4)

为了能够调用泛型方法,必须在编译时知道该类型。您的使用语法无效。

为了能够调用您的方法,您必须使用反射来获取对正确泛型函数的引用,以便您可以调用它。

public static object ToEnum(this string s, Type type)
{
    var eeType = typeof(EnumExt);
    var method = eeType.GetMethod("ToEnum", new[] { typeof(string) })
                       .MakeGenericMethod(type);
    return method.Invoke(null, new[] { s });
}

然后你可以称之为:

Letters letter = (Letters)"A".ToEnum(t);

p.s。,我强烈建议您将变量名更改为其他名称。仅仅因为你可以将变量命名为关键字,并不意味着你应该这样做。

答案 1 :(得分:4)

Enum.Parse(t, @string) as Enum;

这与您发布的解决方案完成相同的事情。

答案 2 :(得分:2)

我不是反思专家,但这有效:

static void Main(string[] args)
{
    Type t = typeof(Letters);

    MethodInfo info = typeof(EnumExt).GetMethod("ToEnum", new Type[] { typeof(string) });
    var method = info.MakeGenericMethod(new Type[] { t });
    var result = (Letters)method.Invoke(null, new [] { "A" });            

    Console.ReadLine();
}

答案 3 :(得分:1)

我认为您的问题可以通过两种方式加以理解: i)您想修复语法错误 ii)您需要为您提供的功能实施工作

对于i),我建议你改变:

Letters letter = "A".ToEnum<t>()

Letters letter = "A".ToEnum<Letters>()

因为泛型是在编译时解决的,因此您不能将变量用作参数。

对于ii),您可以更改提供类型参数的方式,从“generic”参数改为“normal”参数(由Jeff Mercado提出)。通过这样做,您的函数的原型变为:

public static T ToEnum(this string @string, Type t)

最后我要写两条评论:

  • 反思对我的经历非常缓慢。我曾经写过一个汇编解析器,广泛使用枚举上的反射来表示寄存器名称。它曾经运行了几分钟(曾经让VS调试器抱怨无响应)当没有任何反射的等效版本用于在不到10秒的时间内执行时。

  • 正如Jeff Mercado指出的那样,我看不出有任何理由让您对类型名称和变量名称使用相同的声码