您的位置:首页 > 编程语言 > C#

c#编程指南(十六) 连续两周出现在CodeProject Newsletter上代码分析

2010-09-02 17:10 615 查看
首先这个原作者没有提供源代码,这个代码是我根据作者原意写的,这里面包括我前面介绍到的Lambda,LINQ,表达式树,反射和Tuple.

综合了很多新特性,也算是一个不错的综合示例,可以当个考题,哈哈。

问题源自于:如果你有一大堆的各式各样类的示例,现在你要Dump所有这些类的属性,改怎么做?

方法一:使用传统的反射,代码很简单,就是得到某一个类的实例,然后得到类的类型,从类型获得所有的属性,

然后得到具体实例的属性值,并且打印出来。

public void DumpReflection(object[] objs)
{
for (int i = 0; i < objs.Length; i++)
{   //得到object的具体类型的所有属性
PropertyInfo[] pi = objs[i].GetType().GetProperties();
for (int j = 0; j < pi.Length; j++)
{   //得到属性值并且打印
Console.WriteLine(pi[j].Name + " : " + pi[j].GetValue(objs[i],null));
}
}
}


方法二:使用lambda和表达式树获得类的所有属性枚举委托,然后使用委托直接获取属性。

使用LINQ枚举所有属性并且编译成lambda表达式,然后调用每个lambda表达式得到类的属性。

据作者说数据量很大有明显的性能提升。

//#############################################
//
//  dump Hundreds of object , using reflection linq and lambda and delegate generic.
//
//############################################
public void DumpLambda(object[] objs)
{
for (int i = 0; i < objs.Length; i++)
{   //如果使用C# 4.0,直接使用系统提供tuple.
Tuple[] t = GetTuple(objs[i].GetType());
for (int j = 0; j < t.Length; j++)
{  //使用泛型委托,创建委托实例。
Func<object, object> temp = (Func<object, object>)t[j].Delegate;
Console.WriteLine(t[j].Name + " : " + temp(objs[i]));
}
}
}

private Tuple[] GetTuple(Type t)
{
//创建lambda: (o)=>((t)o).pi;(pi为类型的具体属性)
Tuple[] dRet = (from pi in t.GetProperties()  //遍历每个属性
let o = Expression.Parameter(typeof(object), "o")  //设置Lambda表达式参数
select new Tuple(pi.Name, Expression.Lambda(Expression.Convert(Expression.Property(Expression.Convert(o, t), pi), typeof(object)), o).Compile())).ToArray();
//返回tuple类。
return dRet;
}

public class Tuple
{
public string Name { get; set; }
public Delegate Delegate { get; set; }
public Tuple(string name, Delegate d)
{
this.Name = name;
this.Delegate = d;
}
}


上面的例子很好懂,综合了C#很多的知识和特性。

下载:代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐