#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<>))