26

I am trying to get the values from objects inside a list which is part of a main object.

I have the main object which contains various properties which can be collections.

Right now I am trying to figure out how to access a generic list which is contained in the object.

///<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;
}

I've tried to use a SetValue() with MyObject on this, but it errors out with (paraphrased):

object is not of type

private bool isCollection(PropertyInfo p)
{
    try
    {
        var t = p.PropertyType.GetGenericTypeDefinition();
        return typeof(Collection<>).IsAssignableFrom(t) ||
               typeof(Collection).IsAssignableFrom(t);
    }
    catch
    {
        return false;
    }
    }
}
Dustin Kingen
  • 20,677
  • 7
  • 52
  • 92

2 Answers2

36

To Get/Set using reflection you need an instance. To loop through the items in the list try this:

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
}
D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • it seems that this method might work for accessing the list. I have implemented a function to check if the type is a Collection. – Dustin Kingen May 23 '12 at 12:17
  • That should be easy -- `bool isCollection = (oTheList is ICollection);` – D Stanley May 23 '12 at 12:54
  • Nice, but missing an explanation on how to achieve setting nested Lists. For example MyObject.MyList[0].SecondList[1].SomeValue – Best_Where_Gives Feb 07 '18 at 11:31
  • 1
    So iterate on the inner items - it's not that hard. Or ask another question if you're stuck. Do you really expect that all of these answers that you have commented on to give examples for every possible situation, or just the one that _you_ couldn't figure out? – D Stanley Feb 07 '18 at 14:23
  • For those who get error while casting to IList, IEnumerable or ICollection without using a type like IList, add System.Collections to usings. – Can Sep 19 '22 at 07:41
6

See if something like this helps you in the right direction: I got the same error a while back and this code snipped solved my issue.

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
   }
  }
}
CodeLikeBeaker
  • 20,682
  • 14
  • 79
  • 108