定义通用的可通过lambda表达式树来获取属性信息

简介:

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

1
2
3
4
5
6
7
8
一、通过类型来获取属性信息
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表达式树来获取属性信息,使用方便,能解决上述问题,且有智能提示,若出现错误,编译时就能报出,方法定义代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/// <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 ;
}

使用很简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 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

本文转自 梦在旅途 博客园博客,原文链接: http://www.cnblogs.com/zuowj/p/4452046.html  ,如需转载请自行联系原作者
相关文章
|
Kubernetes Nacos 数据库
k8s快速部署nacos单机版
k8s快速部署nacos单机版
|
编解码 测试技术 Android开发
Android经典实战之用 CameraX 库实现高质量的照片和视频拍摄功能
本文详细介绍了如何利用CameraX库实现高质量的照片及视频拍摄功能,包括添加依赖、初始化、权限请求、配置预览与捕获等关键步骤。此外,还特别针对不同分辨率和帧率的视频拍摄提供了性能优化策略,确保应用既高效又稳定。
1309 1
Android经典实战之用 CameraX 库实现高质量的照片和视频拍摄功能
|
JavaScript Java Android开发
kotlin安卓在Jetpack Compose 框架下跨组件通讯EventBus
**EventBus** 是一个Android事件总线库,简化组件间通信。要使用它,首先在Gradle中添加依赖`implementation &#39;org.greenrobot:eventbus:3.3.1&#39;`。然后,可选地定义事件类如`MessageEvent`。在活动或Fragment的`onCreate`中注册订阅者,在`onDestroy`中反注册。通过`@Subscribe`注解方法处理事件,如`onMessageEvent`。发送事件使用`EventBus.getDefault().post()`。
|
安全 Java API
【本地与Java无缝对接】JDK 22外部函数和内存API:JNI终结者,性能与安全双提升!
【9月更文挑战第6天】JDK 22的外部函数和内存API无疑是Java编程语言发展史上的一个重要里程碑。它不仅解决了JNI的诸多局限和挑战,还为Java与本地代码的互操作提供了更加高效、安全和简洁的解决方案。随着FFM API的逐渐成熟和完善,我们有理由相信,Java将在更多领域展现出其强大的生命力和竞争力。让我们共同期待Java编程新纪元的到来!
440 11
|
12月前
|
JavaScript 前端开发 编译器
Vue3基础(26)___defineProps、defineEmits、defineExpose、defineModel组件通信、defineOptions
本文介绍了Vue 3中`<script setup>`语法糖的使用,以及如何在Vue 3的组合式API中使用`defineProps`、`defineEmits`、`defineExpose`和`defineModel`进行组件通信和属性暴露。同时,还解释了`defineOptions`的作用,它可以用来配置组件的选项,例如禁用属性的自动继承。
1114 2
|
缓存 负载均衡 Java
OpenFeign最核心组件LoadBalancerFeignClient详解(集成Ribbon负载均衡能力)
文章标题为“OpenFeign的Ribbon负载均衡详解”,是继OpenFeign十大可扩展组件讨论之后,深入探讨了Ribbon如何为OpenFeign提供负载均衡能力的详解。
OpenFeign最核心组件LoadBalancerFeignClient详解(集成Ribbon负载均衡能力)
|
人工智能 自然语言处理 运维
工业组态 + LLM : 大模型技术引领传统工业软件创新与实践(上)
工业组态 + LLM : 大模型技术引领传统工业软件创新与实践(上)
2569 1
|
Java 编译器 API
Java中的动态编译与运行
Java中的动态编译与运行
|
JSON 安全 fastjson
FastJSON库:JSON处理效率与安全性评估
FastJSON库:JSON处理效率与安全性评估
|
负载均衡 前端开发 Java
Spring Cloud 之 OpenFeign
Spring Cloud OpenFeign是Spring官方的声明式服务调用组件,简化了远程服务调用,使其如同调用本地方法。核心注解包括`@FeignClient`、`@EnableFeignClients`、`@GetMapping`和`@PostMapping`。实践中,通过在`pom.xml`添加依赖,创建Feign接口,配置`@FeignClient`,在启动类启用Feign,以及自定义超时设置来实现远程调用和负载均衡。