c#编程指南(十六) 连续两周出现在CodeProject Newsletter上代码分析
首先这个原作者没有提供源代码,这个代码是我根据作者原意写的,这里面包括我前面介绍到的Lambda,LINQ,表达式树,反射和Tuple.
综合了很多新特性,也算是一个不错的综合示例,可以当个考题,哈哈。
问题源自于:如果你有一大堆的各式各样类的示例,现在你要Dump所有这些类的属性,改怎么做?
方法一:使用传统的反射,代码很简单,就是得到某一个类的实例,然后得到类的类型,从类型获得所有的属性,
然后得到具体实例的属性值,并且打印出来。
1 public void DumpReflection(object[] objs)
2 {
3 for (int i = 0; i < objs.Length; i++)
4 { //得到object的具体类型的所有属性
5 PropertyInfo[] pi = objs[i].GetType().GetProperties();
6 for (int j = 0; j < pi.Length; j++)
7 { //得到属性值并且打印
8 Console.WriteLine(pi[j].Name + " : " + pi[j].GetValue(objs[i],null));
9 }
10 }
11 }
方法二:使用lambda和表达式树获得类的所有属性枚举委托,然后使用委托直接获取属性。
使用LINQ枚举所有属性并且编译成lambda表达式,然后调用每个lambda表达式得到类的属性。
据作者说数据量很大有明显的性能提升。
1 //#############################################
2 //
3 // dump Hundreds of object , using reflection linq and lambda and delegate generic.
4 //
5 //############################################
6 public void DumpLambda(object[] objs)
7 {
8 for (int i = 0; i < objs.Length; i++)
9 { //如果使用C# 4.0,直接使用系统提供tuple.
10 Tuple[] t = GetTuple(objs[i].GetType());
11 for (int j = 0; j < t.Length; j++)
12 { //使用泛型委托,创建委托实例。
13 Func<object, object> temp = (Func<object, object>)t[j].Delegate;
14 Console.WriteLine(t[j].Name + " : " + temp(objs[i]));
15 }
16 }
17 }
18
19 private Tuple[] GetTuple(Type t)
20 {
21 //创建lambda: (o)=>((t)o).pi;(pi为类型的具体属性)
22 Tuple[] dRet = (from pi in t.GetProperties() //遍历每个属性
23 let o = Expression.Parameter(typeof(object), "o") //设置Lambda表达式参数
24 select new Tuple(pi.Name, Expression.Lambda(Expression.Convert(Expression.Property(Expression.Convert(o, t), pi), typeof(object)), o).Compile())).ToArray();
25 //返回tuple类。
26 return dRet;
27 }
28
29 public class Tuple
30 {
31 public string Name { get; set; }
32 public Delegate Delegate { get; set; }
33 public Tuple(string name, Delegate d)
34 {
35 this.Name = name;
36 this.Delegate = d;
37 }
38 }
上面的例子很好懂,综合了C#很多的知识和特性。
下载:代码