首页 > 编程语言 >C# 使用Expression代替反射获取动态类中的值

C# 使用Expression代替反射获取动态类中的值

时间:2023-06-13 12:12:29浏览次数:44  
标签:C# Expression value filedName var type 类中 paramExpr

示例代码:

class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}
 
private object obj = new Person
{
    Id = 123,
    Name = "fred"
};

项目中的Class都是动态生成的,只好用object来存储。

一般常规的方法是用反射去获取对应属性的值,由于速度比较慢,所以使用了Expression去实现。

因为object是动态的类,要取的值也是动态的。所以这里用泛型。

代码如下:

public VT GetValueExpr<T, VT>(T t, string filedName)
{
    var type = t.GetType();
    var paramExpr = Expression.Parameter(type, "x");
    var expr = Expression.Property(paramExpr, filedName);
    var funcCompiled = Expression.Lambda<Func<T, VT>>(expr, paramExpr).Compile();
    var value = funcCompiled.Invoke(t);
    return value;
}

不出意外,代码会报错:

System.ArgumentException: ParameterExpression of type 'ExprDemo.Demo+Person' cannot be used for delegate parameter of type 'System.Object'

这个问题在StackOverflow提问并得到解决了 https://stackoverflow.com/questions/65681824/c-sharp-use-expression-to-get-value-from-an-object

用这段代码就可以了:

public VT GetValueExpr<T, VT>(T t, string filedName)
{
    var type = t.GetType();
    var paramExpr = Expression.Parameter(typeof(T), "x");
    var expr = Expression.Property(Expression.Convert(paramExpr, type), filedName);
    var funcCompiled = Expression.Lambda<Func<T, VT>>(expr, paramExpr).Compile();
    var value = funcCompiled.Invoke(t);
    return value;
}

如果想在此基础上做一些条件判断,可以写成这样:

public bool GetValueExpr<T, VT>(T t, string filedName, Func<VT, bool> func)
{
    var type = t.GetType();
    var paramExpr = Expression.Parameter(typeof(T), "x");
    var expr = Expression.Property(Expression.Convert(paramExpr, type), filedName);
    var funcCompiled = Expression.Lambda<Func<T, VT>>(expr, paramExpr).Compile();
    var value = funcCompiled.Invoke(t);
    return func.Invoke(value);
}

原文链接:https://blog.csdn.net/qq_39930578/article/details/112907837

标签:C#,Expression,value,filedName,var,type,类中,paramExpr
From: https://www.cnblogs.com/nuomibaibai/p/17477178.html

相关文章

  • C# 将 List<dynamic> 转换为 List<string>
    vardlist=newList<dynamic>(){"Guangzhou","Zhuhai","Shenzhen"};提取集合中的所有字符串,忽略所有其他类型,可以使用://Solution1:Includeonlystrings,nonullvalues,noexceptionsthrownvarstrings=dlist.OfType<stri......
  • 将JSON数据导入Excel中
    将JSON数据导入Excel中1、将在浏览器中的JSON数据复制出来,在桌面或者其他位置创建一个文本文件,将JSON数据粘贴进去,并将文件名的后缀改为.JSON格式,例如JSON.JSON{"students":[{"name":"JohnDoe","math":90,"science":85,"english&......
  • Condition类_demo
    参考:https://blog.csdn.net/u014082714/article/details/83927697https://blog.csdn.net/a1439775520/article/details/98471610Resource.javapackagecom.hmb;importjava.util.PriorityQueue;importjava.util.concurrent.locks.Condition;importjava.util.concurr......
  • Ubuntu上安装并使用Docker
    第1步-安装Docker官方Ubuntu存储库中提供的Docker安装包,但是可能不是最新的版本。为了确保我们获得最新版本,我们将从官方Docker存储库安装Docker。为此,我们将添加一个新的资源包,从Docker添加GPG密钥以确保下载有效,然后安装该包。1、首先,更新现有的包列表:sudoaptupdate2、接......
  • JMeter在Mac下的安装
    其实不论操作系统是Windows、Unix(如MacOS)、Linux(如Ubuntu)等,JMeter所需要的基础环境配置都是类似的,本文介绍JMeterforMAC的安装与环境配置。JMeter安装步骤如下:安装JDK安装JMeter1、选择版本截止2018年10月,JMeter的最新版本是5.0,JMeter5.0需要Java8、Java9,所以我们最终......
  • centos系统配置离线yum源
    背景在生产环境中,服务器会由于某些无法连接到公网,而我们想在这样的服务器上安装软件时会出现依赖导致安装失败。我们可以通过配置离线的yum源解决类似问题。大概流程为1、在公网环境下载yum源;2、将yum源上传到服务器;3、配置离线yum源。下面详细介绍如何配置yum源。下载yum源文......
  • Elasticsearch8 单机以及集群部署(docker-compose)
    本文以Elasticsearch8.8.0为例,介绍一下单机安装ES,使用docker-compose方式进行便捷管理需要准本docker环境:一键安装脚本 https://www.cnblogs.com/Alay/p/15433473.html需要准备docker-compose环境:一键安装脚本 https://www.cnblogs.com/Alay/p/15433907.html官网阅......
  • c++ linux基础学习第一课
    课程目标:1.shell命令解析器shell就是命令解析器,将用户命令翻译成内核能够识别的指令。shell常用的快捷键:tab:补齐命令,补齐文件(包括目录和文件)ctrl+a光标移动到头部,ctrl+e光标移动到尾部2.linux下主要目录:/bin保存着二进制文件、可执行程序和shell命令/sbins是superu......
  • C++ Windows.h max宏与std::max冲突问题解决
    C语言引入的宏支持了一定程度的元编程,但它仅仅是简单的字符串替换,这种“六亲不认”的操作很容易导致一些编译错误。这篇文章介绍了一种场景:项目同时引入了老的C头文件,里面用宏定义了一些宏函数;还引入了C++的头文件,里面用其他方式定义了一些同名函数。具体到问题本身,这个......
  • Maven依赖中的scope总结
    scope是限制Dependency的作用范围的,影响maven项目在各个生命周期时导入的package的状态。自2.0.9版本发布后,新增了一种:import,现在已经有了6种scope。下面分别来说明:compile:不声明scope元素的情况下的默认值。compile表示被依赖包需要参与当前项目的编译,包括后续的测试,运行周......