Вопрос по reflection, c#, generics, collections – Использование отражения для получения значений из свойств из списка класса

18

Я пытаюсь получить значения из объектов внутри списка, который является частью основного объекта.

У меня есть основной объект, который содержит различные свойства, которые могут быть коллекциями.

Прямо сейчас я пытаюсь выяснить, как получить доступ к общему списку, который содержится в объекте.

///<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, но с ошибками (перефразировано):

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;
    }
    }
}
@TonyHopkinson Я добавил еще немного информации и соответствующий код. Romoku
Почему вы используете отражение, чтобы сделать это? Я чувствую, что что-то упустил. Tony Hopkinson
Это даже компилируется?oTheList являетсяobject, который не имеет свойства с именемPropertyType. FishBasketGordo
так как список & lt; T & gt; наследует IList вы можете обойти это, перейдя наIList oTheList? Aaron Anodide
Код для соответствующих частей класса, который вы пытаетесь отразить, может быть немного полезным. Tony Hopkinson

Ваш Ответ

2   ответа
22

Чтобы получить / установить с помощью отражения вам нужен экземпляр. Чтобы просмотреть элементы списка, попробуйте это:

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
}
Прекрасно, но отсутствует объяснение того, как добиться установки вложенных списков. Например, MyObject.MyList [0] .SecondList [1] .SomeValue
Так что итерируйте на внутренних предметах - это не так сложно. Или задайте другой вопрос, если вы застряли. Вы действительно ожидаете, что все эти ответы, которые вы прокомментировали, чтобы привести примеры для каждой возможной ситуации, или только тот, которыйyou не могу понять?
Это должно быть легко -bool isCollection = (oTheList is ICollection);
кажется, что этот метод может работать для доступа к списку. Я реализовал функцию, чтобы проверить, является ли тип коллекцией. Romoku
4

Посмотрите, поможет ли что-то подобное в правильном направлении: некоторое время назад я получил ту же ошибку, и этот фрагмент кода решил мою проблему.

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

Похожие вопросы