2011-12-27 60 views
0

在我的程序中,我使用枚举来表示对象的当前状态。我希望能够一一浏览这个枚举的值。枚举值在数值上是连续的并且以0开始的事实是给定的。多个程序集中的动态类型转换行为

虽然试图编写一个递增枚举的函数,但如果它已达到最终结果,则会产生问题。

public static TEnum IncrWrap<TEnum>(TEnum value) 
{ 
    int len = Enum.GetNames(typeof(TEnum)).Length; 
    dynamic wrapper = value; 
    dynamic newValue = ((int)wrapper + 1) % len; 
    return (TEnum)newValue; 
} 

如果IncrWrap方法中相同的组件(项目),其调用它的对象存在,它完美。但是,如果我将它移动到另一个项目(更高级别以便更多的东西可以使用它)并从dll中调用它,那么当它试图将wrapper转换为int并显示消息“无法转换类型”时,我会得到RuntimeBinderException System.Enum'改为'int'“。

怎么了?我不明白为什么从不同的程序集中调用函数会导致函数的行为如此不同。有什么关于dynamic我不明白?这将是很好的,不必使用反射来做到这一点。

回答

1

不幸的是枚举在这里构成了一些问题。首先枚举可以有任何整型,除char之外。其次,不能保证枚举具有递增的基础类型值。最后,C#语言不支持通用类型约束System.Enum,这会有所帮助。说了这么多,我相信你能有点不同解决您的问题:

public static TEnum NextEnum<TEnum>(TEnum value) 
{ 
    if (!typeof(TEnum).IsEnum) 
     throw new ArgumentException("Expected type of System.Enum", "value"); 

    var values = Enum.GetValues(typeof (TEnum)); 
    var index = Array.IndexOf(values, value); 
    return (TEnum)Enum.ToObject(typeof (TEnum), values.GetValue((index + 1) % values.Length)); 
} 

实际上,我惊讶,你都能够找到,使用您的动态解决方案正常工作。

+0

还有一个问题:如果'value'的值不是枚举的定义值之一,Array.IndexOf可能会返回-1。 – phoog 2011-12-28 00:20:04

+0

太棒了!谢谢。仍然好奇为什么我的方法在两种情况下表现不同,但这种解决方案绝对更好。 – Lucina 2011-12-28 01:34:53