2011-10-05 94 views
3

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

下面的代码演示了错误消息作为代码注释的问题。语法错误在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); 

谢谢大家的帮助。

+0

你试图解决的一般问题是什么?它看起来像你试图转换为编译时不知道的类型。那是对的吗? –

+0

这是正确的!我正在试图将解决方案中给出的答案强硬起来。 –

+0

我注意到两种解决方案都以明确的演员结束。如果你可以这样做''A“.ToEnum ();'会很好。话虽如此,我认为这可能是不可能的(不确定C#4中的动态变化是否可能)。如果你能解释为什么你要这样做,那么可能会有更好的方法来解决这个问题。 –

回答

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

即完成同样的事情,你发布的解决方案。

+0

没有什么事情只是为了找到你的目的地是隔壁而整天开车。非常感谢。 –

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(); 
} 
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); 

附言:我强烈要求你改变你的变量名称到别的东西。仅仅因为你可以将变量命名为关键字,并不意味着你应该这样做。

+0

同意删除@string并颁布了更改。像往常一样从网上复制功能。谢谢。 –

1

我认为你的问题可以从两个方面来理解: 我)你要修复一个语法错误 ii)您需要为您提供

对于我的功能设置工作实现),我会建议你改变:

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

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

因为泛型是在编译时解决,因此你不能用瓦里可用作参数。对于ii),你可以改变你提供type参数的方式,从“generic”参数到“normal”参数(如Jeff Mercado提出的)。这样你的函数的原型变为:

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

我的结论有两个备注:

  • 反思是我的经验很慢。我曾经写过一个汇编分析器,对注册名称的枚举大量使用反射。当没有任何反射的等效版本用于在不到10秒的时间内执行时,它曾经运行了几分钟(用于使VS调试器抱怨无响应)。

  • 杰夫梅尔卡多指出,我看不到任何好的理由让你使用的类型名称相同的欧体变量名