本文介绍对列表进行创建及赋值的反射操作

我们现在有TestA、TestB类,TestA中有TestB类型列表的属性List,如下:

  1. 1 public class TestA
  2. 2 {
  3. 3 public List<TestB> List { get; set; }
  4. 4 }
  5. 5 public class TestB
  6. 6 {
  7. 7 public TestB(string name)
  8. 8 {
  9. 9 Name = name;
  10. 10 }
  11. 11 public string Name { get; }
  12. 12 }

下面通过反射,给TestA.List进行赋值,output的期望是 “1,2”

  1. 1 var testA = new TestA();
  2. 2 var list = new List<TestB>() { new TestB("1"), new TestB("2") };
  3. 3 AddValueToListProperty(testA, nameof(TestA.List), list);
  4. 4 var output = string.Join(",", testA.List.Select(i => i.Name));

1. 确定列表及泛型时,可以直接设置属性值

  1. 1 private void AddValueToListProperty(object objectValue, string propertyName, List<TestB> list)
  2. 2 {
  3. 3 var propertyInfo = objectValue.GetType().GetProperty(propertyName);
  4. 4 propertyInfo.SetValue(objectValue, list, null);
  5. 5 }

2.确定属性是列表,但不确定列表的泛型时,通过列表的Add方式进行设置值

List<object> list按上方的方案1,是无法进行赋值的,因为类型不一样。会提示隐示转换异常。

  1. 1 private void AddValueToListProperty(object objectValue, string propertyName, List<object> list)
  2. 2 {
  3. 3 var propertyInfo = objectValue.GetType().GetProperty(propertyName);
  4. 4 var newList = Activator.CreateInstance(typeof(List<>).MakeGenericType(propertyInfo.PropertyType.GenericTypeArguments));
  5. 5 propertyInfo.SetValue(objectValue, newList, null);
  6. 6 var addMethod = newList.GetType().GetMethod("Add");
  7. 7 foreach (var item in list)
  8. 8 {
  9. 9 addMethod.Invoke(newList, new object[] { item });
  10. 10 }
  11. 11 }

如上,我们需要先创建一个空列表,对属性进行初始化。propertyInfo.PropertyType.GenericTypeArguments是列表的泛型类型

然后,获取列表的新增方法 newList.GetType().GetMethod("Add"),将List<object> list一项项添加到列表中。

3.不确定属性是否列表,也不确定列表的泛型,可以如下处理:

  1. 1 private void AddValueToListProperty(object objectValue, string propertyName, object list)
  2. 2 {
  3. 3 var propertyInfo = objectValue.GetType().GetProperty(propertyName);
  4. 4 if (typeof(System.Collections.IList).IsAssignableFrom(propertyInfo.PropertyType))
  5. 5 {
  6. 6 var newList = Activator.CreateInstance(typeof(List<>).MakeGenericType(propertyInfo.PropertyType.GenericTypeArguments));
  7. 7 propertyInfo.SetValue(objectValue, newList, null);
  8. 8 var addMethod = newList.GetType().GetMethod("Add");
  9. 9 foreach (var item in (IEnumerable)list)
  10. 10 {
  11. 11 addMethod.Invoke(newList, new object[] { item });
  12. 12 }
  13. 13 }
  14. 14 else
  15. 15 {
  16. 16 propertyInfo.SetValue(objectValue, list, null);
  17. 17 }
  18. 18 }

如果AddValueToListProperty方法是设置属性值的通用方法,一般可以按上面的方式进行处理。

当然上面的一些代码是简化后的处理,比如判断是否列表,还需要更严谨的判断见《C# 反射 判断类型是否是列表

C# 反射 操作列表类型属性的更多相关文章

  1. redis 的使用 ( list列表类型操作)

    list 数据类型 列表类型 list 类型是一个双向操作 从链表的头部或者尾部添加删除元素 list 既可以用作栈 也可以用作队列 list 链表的类型应用场合: 获取最新的 10 个用户的信息 s ...

  2. java利用反射获取类的属性及类型

    java利用反射获取类的属性及类型. import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.Map ...

  3. redis:list列表类型的操作

    1. list列表类型的操作 1.1. lpush/rpush key value [value ...] 链表的头部(左侧)或尾部(右侧)插入值 语法:lpush key value [value ...

  4. Python列表类型及常用操作

    Python列表类型 1.用途: 存放多个值,可以根据索引存取值 2.定义方式: 在[ ]内用逗号分割开多个任意类型的值 l=['yven','law','lyf'] #l=list(['yven', ...

  5. 通过反射,对javabean属性进行过滤操作

    /** * 根据属性名获取属性值 * @param fieldName 属性名 * @param o 传入对象 * @return */ private Object getFieldValueByN ...

  6. .Net 中的反射(动态创建类型实例) - Part.4

    动态创建对象 在前面节中,我们先了解了反射,然后利用反射查看了类型信息,并学习了如何创建自定义特性,并利用反射来遍历它.可以说,前面三节,我们学习的都是反射是什么,在接下来的章节中,我们将学习反射可以 ...

  7. .Net 中的反射(动态创建类型实例)

    动态创建对象 在前面节中,我们先了解了反射,然后利用反射查看了类型信息,并学习了如何创建自定义特性,并利用反射来遍历它.可以说,前面三节,我们学习的都是反射是什么,在接下来的章节中,我们将学习反射可以 ...

  8. Redis从基础命令到实战之列表类型(List)

    经过上一篇基于Redis散列类型的改造后,实战练习中的商品管理已经具备了增加.修改整体.修改部分属性和分页查询功能,但仍然不支持删除商品的功能.这是因为商品总数是以一个自增数字记录的,且关联了新商品k ...

  9. python列表类型

    列表类型简介 列表类型是一个容器,它里面可以存放任意数量.任意类型的数据. 例如下面的几个列表中,有存储数值的.字符串的.内嵌列表的.不仅如此,还可以存储其他任意类型. >>> L ...

随机推荐

  1. sed随笔

    sed [-hnV]  [-e<script>][-f<script文件>] [文本文件] 参数说明: -e<script>或--expression=<sc ...

  2. 【javascript】关于charCodeAt()方法

    在做算法题目leetcode 2283时,看见某些答案会使用charCodeAt(),因为自己没用过,所以作此纪录 描述在 JavaScript 中,charCodeAt() 是一种字符串方法,用于检 ...

  3. HTTP 认证授权技术归纳

    原文:https://coolshell.cn/articles/19395.html

  4. 基本的dns命令

    打开cmd的方式 win+r 键 输入cmd       管理员方式运行    打开桌面  命令提示符 盘符切换 直接输入要切换的盘 查看当前目录下所有文件   dir 切换目录  cd  /d 跨盘 ...

  5. win10_pyhive链接hive失败,提示:Could not start SASL

    win10_pyhive链接hive失败,提示:Could not start SASL https://blog.csdn.net/weixin_45684985/article/details/1 ...

  6. lua的一些封装方法

    获取点击屏幕坐标 1 function getTouchPosition() 2 local locationX, locationY 3 4 local listener = cc.EventLis ...

  7. BL808:【M1s DOCK开发板】与LVGL 使用体验

    前言 念春时已夏,恋冬雪已融. 总是感叹时光匆匆,便努力在在平凡中挣扎,在平庸中努力,在平淡中积累.奈何时代飞速发展,时间又被工作占用,外加生活中的诱惑又太多了,很多想学.想做.想超越的事,都被抛之一 ...

  8. D - Swap Free Gym - 102423D 二分图性质:补图最大团 = 点的个数 - 最大匹配数

    题意:给你一个串的某些全排列,没有重的,让你求一个最大的集合能有多少个元素,集合的满足条件:交换一个串的任意两个位置上的字母,不能变成集合里的另一个串. 思路:如果一个串不能通过交换一次字母位置变成另 ...

  9. 宕机了,Redis如何避免数据丢失?

      Redis的持久化主要有两大机制,即AOF日志和RDB快照 AOF日志 1.2 AOF日志是如何实现的? 说到⽇志,我们⽐较熟悉的是数据库的写前⽇志(Write Ahead Log, WAL)-- ...

  10. Windows 10 G 神州网信政府版

    ​神州网信政府版2018版:Win10 CMGE_V0-H.1020.000.iso校验码:9484e568c6505f9c4ad5b9fcf7ec8d83588eebfb38089f53e33011 ...