如何将Enum作为参数传入,以便它可用于执行强制转换?

时间:2012-06-23 16:17:58

标签: c# windows-phone-7.1

在下面的存根中,我如何传入(MyEnum)作为参数,以便我可以将此过程与任何枚举一起使用?

public static Enum Proc(this Enum e)
{
Int32 i = (Int32)(MyEnum)e;
...

以下是我提出的解决方案:

public static Enum Next(this Enum e, Type eT)
{
  Int32 i = (Int32)(Object)e;   
  return (Enum)Enum.Parse(eT, Enum.GetName(eT, Enum.GetName(eT, ++i) == null? i = 0 : i));  
}

这个解决方案并不理想,因为我必须这样做才能获得下一个值:

MyEnum e = (MyEnum)e.Next(typeof(MyEnum));

我宁愿做

MyEnum e = e.Next(typeof(MyEnum));

甚至更好:

MyEnum e = e.Next();

任何能提供简单解决方案的人都可以说明问题。

我上面编写的代码在LinqPad中运行良好,但只在WP7中编译,然后在运行时抛出异常(InvalidProgramException)。

2 个答案:

答案 0 :(得分:1)

编辑:我更新了这个以返回列表中的下一个枚举,强类型,无论枚举值的编号是什么。我能够在.NET 4下编译和运行它并且没有在WP7上尝试过,但是我不认为我在SL / WP7中使用了任何缺失/禁用的东西。

public static T Next<T>(this T e) where T : struct
{
    var t = typeof(T);
    if (!t.IsEnum) throw new ArgumentException("T must be an enumerated type");
    if (!Enum.IsDefined(t, e)) throw new ArgumentException();
    var intValue = (int)t.GetField(e.ToString()).GetValue(null);
    var enumValues = t.GetFields(BindingFlags.Public | BindingFlags.Static).Select(x => x.GetValue(null));
    var next = (T?)enumValues.Where(x => (int)x > intValue).Min();
    if (next.HasValue)
        return next.Value;
    else
        return (T)enumValues.Min();
}

它可以简单地用作:

var nextE = e.Next();

答案 1 :(得分:1)

这是一个循环遍历任何enum的值的函数:

static public Enum Cycle(this Enum e)
{
    bool found = false;
    Enum first = null;
    foreach (Enum i in Enum.GetValues(e.GetType()))
    {
        if (first == null)
            first = i;
        if (found)
            return i;
        found = e.Equals(i);
    }
    if (found)
        return first;
    return null;
}

对于没有Enum.GetValues的C#版本,您必须使用这样的方法,该方法仅适用于值从0开始并递增1的枚举:

static public Enum Cycle(this Enum e)
{
    var i = ((IConvertible)e).ToInt64(null) + 1;
    var eT = e.GetType();
    var next = Enum.GetName(eT, i);
    return (Enum)Enum.Parse(eT, next ?? Enum.GetName(eT, 0), false);
}

使用它像:

var nextEnum = (MyEnum)curEnum.Cycle();