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 }
