更新: 2021-06-19

反射 local function

https://stackoverflow.com/questions/43348128/reflection-how-do-i-find-and-invoke-a-local-functon-in-c-sharp-7-0

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 的时候就创建好的了.

https://stackoverflow.com/questions/16838136/create-a-lambda-expression-with-a-new-anonymous-type-at-runtime

一个简单的解决方案是不要用 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# 常用反射和表达式树整理的更多相关文章

  1. c#反射优化 表达式树

    using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; us ...

  2. 添加一种emit的应用,反射发出,较直接调用稍慢,但好过反射与表达式树。

    System.Reflection.MethodInfo mInfo = typeof(TypeParse).GetMethod("Add", System.Reflection. ...

  3. C# 反射 表达式树 模糊搜索

    反射实体T,非datetime字段反射获取表达式树   public static Expression<Func<T, bool>> GetSearchExpression& ...

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

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

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

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

  6. Expression 表达式树学习整理

    整理了一下表达式树的一些东西,入门足够了 先从ConstantExpression 开始一步一步的来吧  它表示具有常量值的表达式 我们选建一个控制台应用程序 ConstantExpression _ ...

  7. C#中分别对委托、匿名方法、Lambda表达式、Lambda表达式树以及反射执行同一方法的过程进行比较。

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. (转)Expression 表达式树学习整理

    原文地址:http://www.cnblogs.com/li-peng/p/3154381.html 整理了一下表达式树的一些东西,入门足够了 先从ConstantExpression 开始一步一步的 ...

  9. 利用表达式树Expression优化反射性能

    最近做了一个.Net Core环境下,基于NPOI的Excel导入导出以及Word操作的服务封装,涉及到大量反射操作,在性能优化过程中使用到了表达式树,记录一下. Excel导入是相对比较麻烦的一块, ...

  10. 【C#表达式树 七】 反射在表达式树中的应用 ListInitExpression

    以下都是反射在表达式树中的应用 对象初始化 Expression.MemberInit 反射获取成员(字段 或者属性),绑定数据,然后生成 成员表达式节点 class Animal { public ...

随机推荐

  1. [oeasy]python0067_ESC键进化历史_键盘演化过程_ANSI_控制序列_转义序列_CSI

    光标位置 回忆上次内容 上次了解了 新的转义模式 \33 逃逸控制字符 esc 这个字符让输出退出标准输出流 进行控制信息的设置 可以设置光标输出的位置 ASR33中的ALT MODE 是 今天的ES ...

  2. [oeasy]python0031_挂起进程_恢复进程_进程切换

    ​ 查看进程 回忆上次内容 上次修改了 $PATH 路径 把当前用户shiyanlou的宿主文件夹 ~ 添加到 $PATH 中 这样 sleep.py 就可以被找到 于是就可以被执行了 还可以把配置 ...

  3. oeasy教您玩转vim - 54 - # 匹配替换

    ​ 查找细节 回忆上节课内容 我们学习了 替换 substitude 替换单行 :s/shiyanlou/oeasy 加上range :3,5s/shiyanlou/oeasy :%s/shiyanl ...

  4. oeasy教您玩转python - 001 - # 换行插入

    ​ 先跑起来 Python 什么是 Python? Python 很好用 适合初学者 而且在各个领域都很强大 ​ 后来居上 ​ 上图可以点开 python3 早已有之 最终逆风翻盘 当然 java 也 ...

  5. 解决react native打包apk文件安装好之后进入应用闪退的问题

    这个是我一个前端前辈帮我弄的,自己解决的时候不行,她去官网找了相关的问题,然后发给我的. react-native android 的release安装包运行闪退,但是debug运行正常 环境:0.6 ...

  6. Docker Compose在Centos下的安装与卸载

    实践环境 Centos7.8 先决条件 已安装Docker Engine 安装Docker Compose 运行以下命令下载稳定版本Docker Compose $ sudo curl -L &quo ...

  7. 常回家看看之largebin_attack

    常回家看看之largebin_attack 先简单介绍一下什么是largebin largebin 是 glibc 的 malloc 实现中用于管理大块内存的一种数据结构.在 glibc 的内存分配中 ...

  8. 云计算:基于Redis的文章投票系统(Python完整版)

    | Redis的安装不懂的可前往 https://www.zeker.top/posts/9d3a5b2a/ 网上搜到的代码很多,但大多都有点小毛病(方法不可用,逻辑错误等) 自己基于网上找到的代码进 ...

  9. windows edge浏览器免费复制网页文字

    复制时,出现上面提示时候 使用edge浏览器打开链接,在http前面加入read: ,然后打开,即可复制 如果用js,可以参考https://www.cnblogs.com/rmticocean/p/ ...

  10. Excel函数-相对引用和绝对引用

    1.相对引用 公式填充时引用的相对位置不变,行和列.序号都相对递增 2.绝对引用 公式填充时应用的单元格绝对位置不变,行和列.序号都不变.绝对引用的符号是"$",也可以快捷键按F4 ...