c# 常用反射和表达式树整理
更新: 2021-06-19
反射 local function
local function 就是 Action or Func 来的.
var www = "";
void Abc(string dada)
{
www = dada;
}
var methodInfo = ((Action<string>)(Abc)).Method;
methodInfo.Invoke(((Action<string>)(Abc)).Target, new object[] { "super man" });
// www = "super man"
可以通过强转换成 Action, 然后通过. Method 获取到 method info, 然后 invoke 的时候它没有 instance 但是有 .Target
想要检查某个 class 是否有实现某个接口, 最好的方式是拿它的 interfaces 出来找
public static bool HasImplementInterface(Type classType, Type interfaceType)
{
var requireIsGenericType = interfaceType.IsGenericType;
var requireIsEmptyGeneric = interfaceType.ContainsGenericParameters; // is empty <,> ?
return classType.GetInterfaces().Where(classInterface =>
{
if (requireIsGenericType && requireIsEmptyGeneric)
{
if (!classInterface.IsGenericType) return false;
return classInterface.GetGenericTypeDefinition() == interfaceType;
}
else
{
return classInterface == interfaceType;
}
}).Count() > 0;
}
更新: 2020-02-22
每次想从 js 写好的代码翻译来 c# 就一定会遇到很多动态语言的问题
想写一个 groupby multiple column
linq 一般上用匿名对象 GroupBy(e => new { e.column1, e.column2 })
但是如果 column 是在 runtime 决定的呢?
直接写不出来, 因为匿名函数不可以简单的用反射写. 匿名函数实在 complie 的时候就创建好的了.
一个简单的解决方案是不要用 column 而是用拼接 string 的方式 group by
https://stackoverflow.com/questions/847066/group-by-multiple-columns
GroupBy(e => e.column1 + "分隔符" + e.column2 );
这个方案好不好,我不是很确定,但是简单是真的, 唯一要注意的是一定要加入分隔符.而且 value 最好都是 string
这种比较简单的场景下会比较安全. 如果不加分隔符 2 个 column 字是有可能撞的,
比如 abc + ef 和 ab + cef 最终都会等于 abcef
所有要特别留意哦.
很久没有写反射了,来整理一下呗.
旧的 : https://www.cnblogs.com/keatkeat/p/4819249.html
创建 Type
public class Abc {}
var type = typeof(Abc); // class to type
var type2 = new Abc().GetType(); // instance to type
有泛型的
public class Abc<T, U> {} var type = typeof(Abc<,>).MakeGenericType(new[] { typeof(string), typeof(string) });
创建实例
public class Abc{
public string name { get; set; }
}
var abc = Activator.CreateInstance(typeof(Abc)) as Abc;
有参数的
public class Abc
{
public Abc(string name) { }
}
var abc = Activator.CreateInstance(typeof(Abc), new object[] { "name" }) as Abc;
有可选参数的
public class Abc
{
public Abc(string name = "dada") { }
}
var abc = Activator.CreateInstance(typeof(Abc), BindingFlags.OptionalParamBinding, null, new object[] { Type.Missing }, CultureInfo.CurrentCulture) as Abc;
几个点留意一下
一定要有 BindingFlags.OptionalParamBinding, 也有人放完. BindingFlags.CreateInstance |
BindingFlags.Public |
BindingFlags.
Instance
BindingFlags.Instance和BindingFlags.Static二者必须有一项或者都有 (refer: https://blog.csdn.net/weixin_38109688/article/details/80147535)
Type.Missing 表示没有传 value
CultureInfo.CurrentCulture 不清楚用来干嘛.
获取方法
refer : https://stackoverflow.com/questions/3631547/select-right-generic-method-with-reflection 2个高赞的回答
一个是使用了 where 的方式去过滤方法.
方法重载主要是看generic, parameters (return 不看)
generic 只看数量 (where T : class 这个不管的)
parameters 就看数量和类型
步骤大概是把方法拿出来, 找 generic count -> make generic -> 检查所有参数数量类型和返回值. 这样就找到了.
第二种方法比较简单但是前提是你必须知道你要的类.
很巧妙的利用了 new Func 和 new Action 来选择方法, 泛型就用 object 后来补上.
public static MethodInfo GetMethod(Type classType, string methodName, Type[] paramTypes = null!, Type[] genericTypes = null!)
{
paramTypes ??= new Type[] { };
genericTypes ??= new Type[] { };
return classType.GetMethods()
.Where(m => m.Name == methodName && m.GetGenericArguments().Count() == genericTypes.Count() && m.GetParameters().Count() == paramTypes.Count())
.Select(m => genericTypes.Count() > 0 ? m.MakeGenericMethod(genericTypes) : m)
.Single(m => m.GetParameters().Select(p => p.ParameterType).SequenceEqual(paramTypes));
} public static ConstructorInfo GetConstructor(Type classType, Type[] paramTypes = null!) {
paramTypes ??= new Type[] { };
return classType.GetConstructors()
.Where(m => m.GetParameters().Count() == paramTypes.Count())
.Single(m => m.GetParameters().Select(p => p.ParameterType).SequenceEqual(paramTypes));
}
获取还没有泛型的 Type
var isOwnedBuilder = builderType.GetGenericTypeDefinition() == typeof(OwnedNavigationBuilder<,>);
lambda 获取属性
// e =>
var entityAsLambdaParameterExp = Expression.Parameter(entityClrType, "e");
// e.type
var entityDotPropertyExp = Expression.Property(entityAsLambdaParameterExp, property);
// e => e.type
var getPropertyLambdaExp = Expression.Lambda(
entityDotPropertyExp,
entityAsLambdaParameterExp
);
判断值类型
if (property.PropertyType.IsValueType || property.PropertyType == typeof(string))
判断有某个标签
var isHtmlContent = property.GetCustomAttribute<HTMLContentAttribute>() != null;
判断 Enum
if (property.PropertyType.IsEnum)
判断泛型 List
var isSSources = property.PropertyType.IsGenericType &&
property.PropertyType.GetGenericTypeDefinition() == typeof(List<>) &&
property.PropertyType.GetGenericArguments()[0] == typeof(SSource);
c# 常用反射和表达式树整理的更多相关文章
- c#反射优化 表达式树
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; us ...
- 添加一种emit的应用,反射发出,较直接调用稍慢,但好过反射与表达式树。
System.Reflection.MethodInfo mInfo = typeof(TypeParse).GetMethod("Add", System.Reflection. ...
- C# 反射 表达式树 模糊搜索
反射实体T,非datetime字段反射获取表达式树 public static Expression<Func<T, bool>> GetSearchExpression& ...
- 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截
程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构 .要想在之后的江湖历练中通关,数据结构必不可少. ...
- 用lambda表达式树替代反射
本节重点不讲反射机制,而是讲lambda表达式树来替代反射中常用的获取属性和方法,来达到相同的效果但却比反射高效. 每个人都知道,用反射调用一个方法或者对属性执行SetValue和GetValue操作 ...
- Expression 表达式树学习整理
整理了一下表达式树的一些东西,入门足够了 先从ConstantExpression 开始一步一步的来吧 它表示具有常量值的表达式 我们选建一个控制台应用程序 ConstantExpression _ ...
- C#中分别对委托、匿名方法、Lambda表达式、Lambda表达式树以及反射执行同一方法的过程进行比较。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- (转)Expression 表达式树学习整理
原文地址:http://www.cnblogs.com/li-peng/p/3154381.html 整理了一下表达式树的一些东西,入门足够了 先从ConstantExpression 开始一步一步的 ...
- 利用表达式树Expression优化反射性能
最近做了一个.Net Core环境下,基于NPOI的Excel导入导出以及Word操作的服务封装,涉及到大量反射操作,在性能优化过程中使用到了表达式树,记录一下. Excel导入是相对比较麻烦的一块, ...
- 【C#表达式树 七】 反射在表达式树中的应用 ListInitExpression
以下都是反射在表达式树中的应用 对象初始化 Expression.MemberInit 反射获取成员(字段 或者属性),绑定数据,然后生成 成员表达式节点 class Animal { public ...
随机推荐
- 使用了条件三元运算符来判断 this.temp.id 是否存在且 mt_qty 是否已被赋值
mt_qty: (this.temp.id && this.temp.mt_qty) ? this.temp.mt_qty : event.wo_wip,在这个修正后的代码中,使用了条 ...
- C# Win10缩放导致Winform字体模糊的解决方法
问题描述 现在的笔记本电脑分辨率很高,基本上能达到1920*1080以上,因为笔记本的屏幕小,在这样的分辨率下一切看着都很小,尤其是文字,根本看不清,所以Win10很人性化的提供了屏幕缩放功能,一般默 ...
- 指针_C
指针的代码 // Code file created by C Code Develop #include "ccd.h" #include "stdio.h" ...
- iOS开发基础136-防暴力点击
要在Objective-C中创建一个高度可复用的工具类,以防止按钮的暴力点击,并且使用切面编程(AOP)的方式,我们可以考虑使用Aspects这个库来实现方法的拦截.以下是具体的实现步骤: 第一步:引 ...
- hbuilder打包的应用上架appstore屏幕快照的生成方法
当我们使用hbuiderX或apicloud这些打包工具进行打包的时候,我们需要将打包好的ipa文件进行上架,但是你会发现,我们上架的时候需要上传5.5寸的iphone.6.5寸的iphone X和两 ...
- Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock error was 14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 未知的错误"解决yum下载报错
报错信息 │ (SSH client, X server and network tools) │ │ │ │ ⮞ SSH session to root@192.168.117.166 │ │ • ...
- 【Scala】09 偏函数 PartialFunction
更像是策略函数 可拆分成一个部分,是若干个函数的组合 package cn object HelloScala { def main(args: Array[String]): Unit = { // ...
- 【C】Re03
一.变量 变量存储了两个东西: 1.内存空间地址 2.内存空间存放的值 本质是给内存地址起了一个别名,允许我们通过别名对内存进行访问 void variable01() { int a = 100; ...
- vue&element项目实战 之element使用&用户&字典模块实现
6.用户模块 用户模块api import request from '@/utils/request' export function login(data) { return request({ ...
- 《最新出炉》系列小成篇-Python+Playwright自动化测试-67 - 模拟手机浏览器兼容性测试
1.简介 在日常工作中,我们会遇到需要使用不同的硬件设备测试兼容性的问题,尤其是现在手机型号基本上是每个厂家每年发布一款新机型,而且手机的屏幕大小分辨率五花八门的,我们基本不可能全部机型都用真机测试一 ...