给定我知道是列表的来自System relfection的PropertyInfo对象,我如何访问列表并操纵列表中的项目?

问题描述

因此,我对Reflection并不陌生,但最近发现它非常有用。但是我遇到了障碍。基本上现在,我正在循环通过反射获得的类的属性,并根据该属性包含的数据类型(int,字符串,枚举等)执行某些操作,并在此过程中修改属性中的数据。使用propertyInfo.SetValue()方法非常简单,该方法适用于我需要处理的所有其他情况。但是,对于列表我不能只设置值,因为我没有尝试设置列表的值,因此我希望能够添加删除列表中的项目以及更改列表中项目的值。而这一切都是动态的。以下是我要执行的操作的示例:

MyAbstractClass classInstance; //this may contain one of many classes inheriting from 'MyAbstractClass'

PropertyInfo[] properties = classInstance.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
     //this would be proceeded by other type case checks,this is the case that it's a list
     else if (prop.PropertyType.GetInterface(typeof(List<>).FullName) != null)
     {
          Type contentType = prop.PropertyType.GetGenericArguments()[0]; //get the type of data held in list
          //BEGIN EXAMPLES OF WHAT I'D LIKE TO DO
          prop.GetValue(classInstance).Add(Activator.CreateInstance(contentType));
          prop.GetValue(classInstance).RemoveAt(3);
          prop.GetValue(classInstance)[1] = someDataThatIKNowIsCorrectType;
     }
}

我通过互联网研究发现了很多其他东西,学到了很多东西,但是我找不到我试图解决的难题的最后一部分,或者潜在地无法找到解决我的问题的方法如果我确实看到过它。

感谢您的帮助!

解决方法

您可以将值转换为IList并使用Add(object value)方法:

class MyClass
{
    public List<int> MyProperty { get; set; }
}

var x = new MyClass {MyProperty = new List<int>()};
var list = (IList)x.GetType().GetProperty(nameof(MyClass.MyProperty)).GetValue(x);
list.Add(1);
list.Add(2);
list.RemoveAt(0);
list[0] = 3;
Console.WriteLine(list[0]); // prints 3

我个人也将实施属性类型检查,例如:

var isIList = prop.PropertyType.GetInterfaces().Any(i => i.IsConstructedGenericType && i.GetGenericTypeDefinition() == typeof(IList<>))