zoukankan      html  css  js  c++  java
  • C# 反射 操作列表类型属性

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    项目管理--PMBOK 读书笔记(4)【项目整合管理】
    数论(二)
    数论(一)
    Jmeter连接mysql数据库
    minicom工具的使用
    centos7 docker 挂载文件思路
    go语言的init函数
    go操作elasticsearch
    UML交互图
    Linux环境下mysql的安装
  • 原文地址:https://www.cnblogs.com/kybs0/p/15112008.html
Copyright © 2011-2022 走看看