Учитывая объект PropertyInfo из System relfection, который, как я знаю, является списком, как я могу получить доступ к списку и манипулировать элементами в списке?

#c# #list #system #system.reflection #propertyinfo

#c# #Список #система #system.reflection #propertyinfo

Вопрос:

Итак, я довольно новичок в Reflection, но недавно нашел его чрезвычайно полезным. Но я столкнулся с препятствием. По сути, прямо сейчас я перебираю свойства класса, которые я получил с помощью отражения, и делаю что-то в зависимости от того, какие данные содержит свойство (int, string, enum и т. Д.), И при этом изменяю данные в свойстве. Это было довольно просто, используя метод 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;
     }
}
  

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

Спасибо за помощь!

Ответ №1:

Вы можете привести значение к 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 amp;amp; i.GetGenericTypeDefinition() == typeof(IList<>))