使用反射从一个类的列表中获取属性值

26

我正在尝试获取包含在主对象中的列表中对象的值。

我有一个包含各种属性的主对象,这些属性可以是集合。

现在我正在努力找出如何访问包含在对象中的通用列表。

///<summary>
///Code for the inner class
///</summary>
public class TheClass
{
    public TheClass();

    string TheValue { get; set; }
} //Note this class is used for serialization so it won't compile as-is

///<summary>
///Code for the main class
///</summary>
public class MainClass
{
    public MainClass();

    public List<TheClass> TheList { get; set; }
    public string SomeOtherProperty { get; set; }
    public Class SomeOtherClass { get; set }
}


public List<MainClass> CompareTheValue(List<object> MyObjects, string ValueToCompare)
{ 
    //I have the object deserialised as a list
    var ObjectsToReturn = new List<MainClass>();
    foreach(var mObject in MyObjects)
    {

        //Gets the properties
        PropertyInfo piTheList = mObject.GetType().GetProperty("TheList");

        object oTheList = piTheList.GetValue(MyObject, null);


        //Now that I have the list object I extract the inner class 
        //and get the value of the property I want
        PropertyInfo piTheValue = oTheList.PropertyType
                                          .GetGenericArguments()[0]
                                          .GetProperty("TheValue");

        //get the TheValue out of the TheList and compare it for equality with
        //ValueToCompare
        //if it matches then add to a list to be returned

        //Eventually I will write a Linq query to go through the list to do the comparison.
        ObjectsToReturn.Add(objectsToReturn);

    }
return ObjectsToReturn;
}

我尝试使用SetValue()来对MyObject进行操作,但出现错误(引述):

对象类型不符

private bool isCollection(PropertyInfo p)
{
    try
    {
        var t = p.PropertyType.GetGenericTypeDefinition();
        return typeof(Collection<>).IsAssignableFrom(t) ||
               typeof(Collection).IsAssignableFrom(t);
    }
    catch
    {
        return false;
    }
    }
}

2
你正在尝试反射的类的相关部分的代码可能会有些有用。 - Tony Hopkinson
由于List<T>继承自IList,您是否可以通过更改为IList oTheList来解决这个问题? - Aaron Anodide
2
这个能编译吗?“oTheList”是一个“object”,它没有名为“PropertyType”的属性。 - FishBasketGordo
为什么你要用反射来做这个?我感觉好像有些东西我没看懂。 - Tony Hopkinson
显示剩余2条评论
2个回答

36

使用反射进行获取/设置需要一个实例。要循环遍历列表中的项目,请尝试以下内容:

PropertyInfo piTheList = MyObject.GetType().GetProperty("TheList"); //Gets the properties

IList oTheList = piTheList.GetValue(MyObject, null) as IList;

//Now that I have the list object I extract the inner class and get the value of the property I want

PropertyInfo piTheValue = piTheList.PropertyType.GetGenericArguments()[0].GetProperty("TheValue");

foreach (var listItem in oTheList)
{
    object theValue = piTheValue.GetValue(listItem, null);
    piTheValue.SetValue(listItem,"new",null);  // <-- set to an appropriate value
}

看起来这种方法可能适用于访问列表。我已经实现了一个函数来检查类型是否为集合。 - Dustin Kingen
很简单 – bool isCollection = (oTheList is ICollection); - D Stanley
不错,但缺少如何设置嵌套列表的说明。例如MyObject.MyList [0] .SecondList [1]。SomeValue - Best_Where_Gives
1
所以迭代内部项目-这并不难。如果你卡住了,或者有其他问题,请再提问。你真的期望所有这些你已经评论过的答案都为每种可能的情况给出示例,还是只有那个_你_想不通的情况? - D Stanley
对于那些在转换为IList、IEnumerable或ICollection时出现错误且没有使用像IList<T>这样的类型的人,请将System.Collections添加到usings中。 - Can

6
看看这个是否能帮助你朝着正确的方向前进:我以前也遇到了同样的错误,这段代码片段解决了我的问题。
PropertyInfo[] properties = MyClass.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
  if (property.Name == "MyProperty")
  {
   object value = results.GetType().GetProperty(property.Name).GetValue(MyClass, null);
   if (value != null)
   {
     //assign the value
   }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接