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#很多的知识和特性。

下载:代码

你可能感兴趣的:(project)