我们一般获取某个类型或对象的属性信息均采用以下几种方法:

一、通过类型来获取属性信息
var p= typeof(People).GetProperty("Age");//获取指定属性
var ps = typeof(People).GetProperties();//获取类型的所有属性 二、通过实例来获取属性信息
People people = new People();
var pro = people.GetType().GetProperty("Age");
var pros = people.GetType().GetProperties();

这两种方法都有其弊端,第一种与第二种方法,在获取单个属性信息时,都需要硬编码写入常量属性名称,这样在编译时并不会报错,只有在运行时才知道异常,第二种方法若只是需要获取属性的类型名称等基本信息,不需要属性的值,就不需要实例化类型。

鉴于以上原因,我定义了通用的可通过lambda表达式树来获取属性信息,使用方便,能解决上述问题,且有智能提示,若出现错误,编译时就能报出,方法定义代码如下:

        /// <summary>
/// 获取指定属性信息(非String类型存在装箱与拆箱)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="select"></param>
/// <returns></returns>
public static PropertyInfo GetPropertyInfo<T>(Expression<Func<T,dynamic>> select)
{
var body = select.Body;
if (body.NodeType == ExpressionType.Convert)
{
var o = (body as UnaryExpression).Operand;
return (o as MemberExpression).Member as PropertyInfo;
}
else if (body.NodeType == ExpressionType.MemberAccess)
{
return (body as MemberExpression).Member as PropertyInfo;
}
return null;
} /// <summary>
/// 获取指定属性信息(需要明确指定属性类型,但不存在装箱与拆箱)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TR"></typeparam>
/// <param name="select"></param>
/// <returns></returns>
public static PropertyInfo GetPropertyInfo<T, TR>(Expression<Func<T, TR>> select)
{
var body = select.Body;
if (body.NodeType == ExpressionType.Convert)
{
var o = (body as UnaryExpression).Operand;
return (o as MemberExpression).Member as PropertyInfo;
}
else if (body.NodeType == ExpressionType.MemberAccess)
{
return (body as MemberExpression).Member as PropertyInfo;
}
return null;
} /// <summary>
/// 获取类型的所有属性信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="select"></param>
/// <returns></returns>
public static PropertyInfo[] GetPropertyInfos<T>(Expression<Func<T,dynamic>> select)
{
var body = select.Body;
if (body.NodeType == ExpressionType.Parameter)
{
return (body as ParameterExpression).Type.GetProperties();
}
else if(body.NodeType==ExpressionType.New)
{
return (body as NewExpression).Members.Select(m => m as PropertyInfo).ToArray();
}
return null;
}

使用很简单:

// People类型定义
class People
{
public string Name
{ get; set; } public int Age
{ get; set; } public string Sex
{ get; set; } public bool IsBuyCar
{ get; set; } public DateTime? Birthday
{ get; set; }
} //以下是使用方法: var p = GetPropertyInfo<People>(t => t.Age);//获取指定属性
var ps1 = GetPropertyInfos<People>(t => t);//获取类型所有属性
var ps2 = GetPropertyInfos<People>(t => new { t.Name, t.Age });//获取部份属性

  

注意dynamic类型也存在装箱与拆箱的问题,详见这篇博文:http://www.cnblogs.com/yank/p/4177619.html

定义通用的可通过lambda表达式树来获取属性信息的更多相关文章

  1. 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截

    程序猿修仙之路--数据结构之你是否真的懂数组?   数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构  .要想在之后的江湖历练中通关,数据结构必不可少. ...

  2. C# Lambda表达式详解,及Lambda表达式树的创建

    最近由于项目需要,刚刚学完了Action委托和Func<T>委托,发现学完了委托就必须学习lambda表达式,委托和Lambda表达式联合起来,才能充分的体现委托的便利.才能使代码更加简介 ...

  3. Lambda表达式树解析(下)

    概述 前面章节,总结了Lambda树的构建,那么怎么解析Lambda表达式树那?Lambda表达式是一种委托构造而成,如果能够清晰的解析Lambda表达式树,那么就能够理解Lambda表达式要传递的正 ...

  4. Lambda表达式树解析(下)包含自定义的provider和查询

    概述 前面章节,总结了Lambda树的构建,那么怎么解析Lambda表达式树那?Lambda表达式是一种委托构造而成,如果能够清晰的解析Lambda表达式树,那么就能够理解Lambda表达式要传递的正 ...

  5. 用lambda表达式树替代反射

    本节重点不讲反射机制,而是讲lambda表达式树来替代反射中常用的获取属性和方法,来达到相同的效果但却比反射高效. 每个人都知道,用反射调用一个方法或者对属性执行SetValue和GetValue操作 ...

  6. EntityFramework动态多条件查询与Lambda表达式树

              在常规的信息系统中, 我们有需要动态多条件查询的情况, 例如UI上有多个选择项可供用户选择多条件查询数据. 那么在.net平台Entity Framework下, 我们用Lambd ...

  7. 动态拼接lambda表达式树

    前言 最近在优化同事写的代码(我们的框架用的是dapperLambda),其中有一个这样很普通的场景——界面上提供了一些查询条件框供用户来进行过滤数据.由于dapperLambda按条件查询时是传入表 ...

  8. 将简单的lambda表达式树转为对应的sqlwhere条件

    1.Lambda的介绍 园中已经有很多关于lambda的介绍了.简单来讲就是vs编译器给我带来的语法糖,本质来讲还是匿名函数.在开发中,lambda给我们带来了很多的简便.关于lambda的演变过程可 ...

  9. Lambda表达式树构建(上)

    概述 Lambda是C#常用的语句,采用委托等方式,来封装真实的代码块.Lambda其实就是语法糖,是一个匿名函数,是一种高效的类似于函数式编程的表达式,Lambda简化了开发中需要编写的代码量.它可 ...

随机推荐

  1. 使用knockout-sortable实现对自定义菜单的拖拽排序

    在开始之前,照例,我们先看效果和功能实现. 关于自定义菜单的实现,这里就不多说了,需要了解的请访问:http://www.cnblogs.com/codelove/p/4838766.html 这里需 ...

  2. 收录.NET跨平台及跨数据库的博文...

    本帖,将持续收录.NET跨平台及跨数据库的博文... VS2012+EF6+Mysql配置心路历程: http://www.cnblogs.com/gameman/p/3773240.html ASP ...

  3. seajs 源码阅读笔记

    代码概览 src目录文件列表如下: 代码以模块化的方式来组织,构建的时候会合并为一个js文件(sea.js 或 sea-debug.js),其中,intro.js和 outro.js 分别是这个js文 ...

  4. 我的ORM之七-- 权限

    我的ORM索引 权限范围 权限可以控制以下部分: 页面 按钮 表格列 (未完成) 菜单表的行 其中: 页面权限,需要在程序请求之前进行判断. 按钮权限,表格列权限,需要在请求页面之后,通过JavaSc ...

  5. java提高篇(二一)-----ArrayList

    一.ArrayList概述       ArrayList是实现List接口的动态数组,所谓动态就是它的大小是可变的.实现了所有可选列表操作,并允许包括 null 在内的所有元素.除了实现 List ...

  6. AngularJS快速入门指南17:Includes

    使用AngularJS,你可以在HTML中包含其它的HTML文件. 在HTML中包含其它HTML文件? 当前的HTML文档还不支持该功能.不过W3C建议在后续的HTML版本中增加HTML import ...

  7. javascript事件监听与事件委托

      事件监听与事件委托 在js中,常用到element.addEventListener()来进行事件的监听.但是当页面中存在大量需要绑定事件的元素时,这种方式可能会带来性能影响.此时,我们可以用事件 ...

  8. CentOS 6.6下Redis安装配置记录

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/120.html?1455855209 在先前的文章中介绍过redis,以下 ...

  9. 关于C#中的线程重启的问题

    首先不管是C#也好,还是java也好,对于已经Abort的线程是无法再次Start的,除非是声明私有变量new一个新的线程,网上也有很多人说可以Suspend挂起线程,然后再Resume继续,但是相信 ...

  10. 每天一个linux命令(22):find 命令的参数详解

    find一些常用参数的一些常用实例和一些具体用法和注意事项. 1.使用name选项: 文件名选项是find命令最常用的选项,要么单独使用该选项,要么和其他选项一起使用.  可以使用某种文件名模式来匹配 ...