随笔-51  评论-726  文章-1  trackbacks-0

Let Enum Enumerable

先来看一个无比简单的Enum

/// <summary>
/// 中国式英语
/// </summary>
enum Chinglish
{ 
    Niubility,
    Zhuangbility,
    Shability,
    Erbility,
}

 

(一个小插曲:以上中国式英语的4个enum值来自于——

Many people think they are full of niubility and like to play zhuangbility, which only reflect their shability and erbility

至于中文意思可以google一下)

最原始的Enum遍历

一般来说,如果我们想遍历以上的Enum, 其中一种做法是:

Array values = Enum.GetValues(typeof(Chinglish )); 
foreach (var value in values)
{
    Chinglish e =(Chinglish)value;
    //do sth. ...
}

 

我不知道是否还有更简单的写法,但如果每次遍历一个Enum类型就要像上面这么写,确实有点...

不美观的地方有两点:

1. typeof( Chinglish )

而 Enum.GetValues(typeof(Chinglish ));  返回的是Array类型,使用时又要cast一下。

2. Chinglish e =(Chinglish)value;

也就是要类型转换才能做下一步事情。

Enum Foreach 封装

这两个不雅的地方促使我要把它进行封装,最终得到以下写法:

Enum<Chinglish>.Foreach(e => Console.WriteLine(e));

 

实现很简单:

public class Enum<T>
{
    public static void Foreach(Action<T> action)
    {
        Array values = Enum.GetValues(typeof(T));
        foreach (var value in values)
        {
            action((T)value);
        }
    }
}

 

这个Enum<T>.Foreach 方法已经帮了我很大忙了,让我可以一句代码就实现对Enum进行遍历。后来,我又发现仅是Foreach还不够用,有时候我还要对Enum进行查询操作,自然而然想为它添加类似 Linq 的Where 方法:

public static IEnumerable<T> Where(Func<T, bool> func)

 

既然Where有了,那么Single也不应该少了吧:

public static T Single(Func<T, bool> func)

... ...

Let Enum Enumerable

这种“贪念”会无限扩展,导致我干脆一不做二不休,直接来个AsEnumerable 让其返回一个IEnumerable<T> 类型,那么想干啥都可以了,Where、Single、Foreach不在话下 :

//Let Enum Enumerable
var en = Enum<Chinglish>.AsEnumerable();
//Print
en.ForEach(e => Console.WriteLine(e));
//Call other test method
en.ForEach(e => EnumMethod(e));
//Filter
var filter = en.Where(c => (int)c > 2);

 

总结

我在应用中需要遍历enum 或者对其做更复杂的操作,一般有两种情况:

1. 测试代码

    如en.ForEach(e => EnumMethod(e)); 是否覆盖EnumMethod里的所有情况。

2. 结合enum的其他扩展做其他事情。

 

完整源代码:

public class Enum<T>
{
    public static IEnumerable<T> AsEnumerable()
    {
        EnumQuery<T> query = new EnumQuery<T>();
        return query;
    }
}

class EnumQuery<T> : IEnumerable<T>
{
    private List<T> list;

    #region IEnumerable<T> Members

    public IEnumerator<T> GetEnumerator()
    {
        Array values = Enum.GetValues(typeof(T));
        list = new List<T>(values.Length);
        foreach (var value in values)
        {
            list.Add((T)value);
        }
        return list.GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion
}

 

 

 

 

 

posted on 2009-09-30 11:29 CoolCode 阅读(478) 评论(5) 编辑 收藏