场景

从接口返回的数据是集合,却是 object 类型的。这个时候需要遍历这个集合。现提供两种方法。

方法一:

因为集合是可枚举的,所以可以尝试转为 IEnumerable 类型,然后遍历即可。

static void Main(string[] args)
{
var list = new List<Foo> {
new Foo{ Id = 1, Name = "aaa" },
new Foo{ Id = 2, Name = "bbb" },
new Foo{ Id = 3, Name = "ccc" }
}; ReflectionCollection(list);
} private static void ReflectionCollection(object input)
{
var collection = input as IEnumerable;
if (collection is not null)
{
var enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine($"{JsonSerializer.Serialize(enumerator.Current)}");
}
}
}

方法二:

使用表达式树。

private static void ExpressionTreeAccessCollection(object input)
{
var type = input.GetType();
var inputParameterExp = Expression.Parameter(typeof(object), "input");
var callbackParameterExp = Expression.Parameter(typeof(Action<object>), "callback");
var countVariableExp = Expression.Variable(typeof(int), "count");
var tempVariableExp = Expression.Variable(typeof(int));
var itemVariableExp = Expression.Variable(typeof(object), "item");
var convertExp = Expression.Convert(inputParameterExp, type);
var voidLabel = Expression.Label(); // 方法一
var indexProperty = type.GetDefaultMembers().OfType<PropertyInfo>()
.First(_ => _.GetIndexParameters().Any(_ => _.ParameterType == typeof(int))); // 方法二
//var toArrayMethod = type.GetMethod(nameof(List<object>.ToArray));
//var toArrayExp = Expression.Call(convertExp, toArrayMethod);
//var arrayIndexExp = Expression.ArrayIndex(toArrayExp, new Expression[] { tempVariableExp }); // 调用外部方法
//var printItemMethod = typeof(Program).GetMethod(nameof(PrintItem), BindingFlags.NonPublic | BindingFlags.Static); var blockExp = Expression.Block(
new ParameterExpression[] { countVariableExp, tempVariableExp, itemVariableExp },
Expression.Assign(
countVariableExp,
Expression.Property(convertExp, "Count")
),
Expression.Assign(tempVariableExp, Expression.Constant(0)),
Expression.Loop(
Expression.IfThenElse(
Expression.LessThan(tempVariableExp, countVariableExp),
Expression.Block(
new ParameterExpression[] { itemVariableExp },
// 方法一
Expression.Assign(itemVariableExp, Expression.MakeIndex(convertExp, indexProperty, new ParameterExpression[] { tempVariableExp })), // 方法二
//Expression.Assign(itemVariableExp, arrayIndexExp), // 调用外部方法
//Expression.Call(null, printItemMethod, itemVariableExp), // 调用回调函数
Expression.Invoke(callbackParameterExp, itemVariableExp),
Expression.AddAssign(tempVariableExp, Expression.Constant(1, typeof(int)))
),
Expression.Block(
Expression.Return(voidLabel)
)
)
),
Expression.Label(voidLabel)
); var lambda = Expression.Lambda<Action<object, Action<object>>>(blockExp, new ParameterExpression[] { inputParameterExp, callbackParameterExp });
var func = lambda.Compile();
func(input, item => {
Console.WriteLine($"Callback: {JsonSerializer.Serialize(item)}");
});
} private static void PrintItem(object item)
{
Console.WriteLine($"PrintItem: {JsonSerializer.Serialize(item)}");
}

Expression Tree 遍历集合的更多相关文章

  1. Reflection和Expression Tree解析泛型集合快速定制特殊格式的Json

    很多项目都会用到Json,而且大部分的Json都是格式固定,功能强大,转换简单等,标准的key,value集合字符串:直接JsonConvert.SerializeObject(List<T&g ...

  2. 【C#表达式树 开篇】 Expression Tree - 动态语言

    .NET 3.5中新增的表达式树(Expression Tree)特性,第一次在.NET平台中引入了"逻辑即数据"的概念.也就是说,我们可以在代码里使用高级语言的形式编写一段逻辑, ...

  3. 深入学习C#匿名函数、委托、Lambda表达式、表达式树类型——Expression tree types

    匿名函数 匿名函数(Anonymous Function)是表示“内联”方法定义的表达式.匿名函数本身及其内部没有值或者类型,但是可以转换为兼容的委托或者表达式树类型(了解详情).匿名函数转换的计算取 ...

  4. Lambda表达式遍历集合

    1.Collection Java 8 为Iterable接口新增了一个forEach(Consumer action)默认方法,该方法所需参数的类型是一个函数式接口,而Iterable接口是Coll ...

  5. Expression Tree Basics 表达式树原理

    variable point to code variable expression tree data structure lamda expression anonymous function 原 ...

  6. Expression Tree 扩展MVC中的 HtmlHelper 和 UrlHelper

    表达式树是LINQ To everything 的基础,同时各种类库的Fluent API也 大量使用了Expression Tree.还记得我在不懂expression tree时,各种眼花缭乱的A ...

  7. 使用Expression Tree构建动态LINQ查询

    这篇文章介绍一个有意思的话题,也是经常被人问到的:如何构建动态LINQ查询?所谓动态,主要的意思在于查询的条件可以随机组合,动态添加,而不是固定的写法.这个在很多系统开发过程中是非常有用的. 我这里给 ...

  8. JAVA基础学习之final关键字、遍历集合、日期类对象的使用、Math类对象的使用、Runtime类对象的使用、时间对象Date(两个日期相减)(5)

    1.final关键字和.net中的const关键字一样,是常量的修饰符,但是final还可以修饰类.方法.写法规范:常量所有字母都大写,多个单词中间用 "_"连接. 2.遍历集合A ...

  9. .NET Expression Tree

    Expression Tree 第一个简单的例子. [TestMethod] public void GodTest() { Expression<Func<int, int, int&g ...

随机推荐

  1. 【Paper】智能家居

    From: http://liudongdong1.github.io keyword: Human-centered computing , LoRa Paper: WIDESEE WIDESEE: ...

  2. .net core 通过动软连接数据库

    .net core 与动软 首先创建asp.net core 或者 .net core 控制台程序.不需急着创建web.config 文件. 通过NuGet加个ado的包 System.Data.Sq ...

  3. 微信小程序自定义顶部

    wxml <view style="height:{{titleHeight}}px;background:{{background}}" class="user- ...

  4. Java常用类之时间类

    JDK8之前日期时间API 1. java.lang.System类 2. java.util.Date类 3. java.text.SimpleDateFormat类 4. java.util.Ca ...

  5. Linux初探之如何查看帮助文档自学命令

    linux命令种类繁多,参数各异,要每个都记住除非是过目不忘的神人,否则你只能记住常用的那几个,等到 要用时还是得靠--help,man,info这些命令去读文档,可是这些文档看起来也不那么直观,所以 ...

  6. java web课程设计(简单商城的前后端双系统,基于maven三模块开发)

    1.系统分析 1.1需求分析 实现一个简单但功能完整的商城项目,从设计到实现,规范化完成该项目,锻炼javaweb项目的编写能力,理解软件工程的软件设计思想 1.2编程技术简介 本次课程主要使用的软件 ...

  7. 回顾games101中的SSAA和MSAA

    回顾games101中的AA(抗锯齿) 前言 善于进行课后总结,可以更加巩固自己的知识和具体细节 锯齿(走样)产生的原因 本质上,在光栅化阶段中,用有限离散的数据想表示连续的(类似三角形的某一边),就 ...

  8. CSS3 animaion 和 transition 比较

    animation是CSS3的动画属性,可以设置以下六种属性. transition是CSS3的过度属性,可以设置以下四种属性. 从属性上分析,animation可以设定循环次数. 其次,两者的触发条 ...

  9. adb shell 查看当前与用户交互的 activity

    adb shell dumpsys activity activities | grep mActivityComponent

  10. vue ele 日期时间格式限制不能早于当天,时间转换成时间戳 进行比较

    <el-date-picker             value-format="yyyy-MM-dd HH:mm:ss"             v-model=&quo ...