Получить значение из переопределения с использованием отражения

#c# #reflection

#c# #отражение

Вопрос:

Я хочу получить значение из виртуального свойства из унаследованного класса, смотрите мой код ниже:

Базовый класс:

 public class TestBaseClass
{
   public virtual int Index { get; }
}
  

Унаследованный класс:

 public class TestInheritedClass : TestBaseClass
{
   public override int Index => 100; // I want to get this value using reflection
}
  

Мой код:

 static void Main(string[] args) 
{
   var assemblies = Assembly.LoadFile(args[0]);
   foreach(var type in assembly.ExportedTypes)
   {
      if(type.IsSubclassOf(typeof(TestBaseClass))
      {
         foreach(var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
         {
            var value = prop.GetValue(typeof(int), null); // I expect to return 100 from override Index value
         }
      }
   }
}
  

Я что-то пропустил или я все сделал неправильно? Я пытаюсь получить значение 100 из виртуального свойства. Есть ли способ получить значение?

Комментарии:

1. Вы что-то пропустили. Index это свойство экземпляра: вам нужен экземпляр TestInheritedClass , чтобы получить к нему доступ. Вы должны передавать этот экземпляр в prop.GetValue , но вы передаете typeof(int) , то есть экземпляр Type объекта. Не имеет значения, что все экземпляры TestInheritedClass будут возвращать одно и то же значение: среда выполнения этого не знает, и язык работает не так

2. Это не статическое свойство, поэтому вам понадобится экземпляр, чтобы заставить это работать. Вы можете использовать Activator. Создайте Instance и используйте экземпляр в вашем вызове GetValue

3. вам нужно выполнить var obj = Activator.CreateInstance(type); внешний цикл foreach, а затем передать obj в prop.GetValue метод в качестве первого параметра как var value = prop.GetValue(obj, null);

4. Большое вам спасибо, я справился с этим, вы, ребята, очень помогли. 🙂

Ответ №1:

Есть ли способ получить значение?

Да, есть способ. Давайте сначала посмотрим, что вы там сделали:

 prop.GetValue(typeof(int), null)
  

Вы используете эту перегрузку PropertyInfo.GetValue . Он ожидает экземпляр объекта, из которого нужно получить значение в качестве первого параметра. Вместо этого вы передаете typeof(int) . Это не экземпляр TestInheritedClass .
Я проигнорирую второй параметр здесь, потому что мы не говорим об индексаторе.
Вы можете прочитать об этом параметре в документации.

Вместо этого вы должны создать экземпляр TestInheritedClass first:

 var instance = Activator.CreateInstance(typeof(TestInheritedClass));
  

Затем используйте его следующим образом:

 if (type.IsSubclassOf(typeof(TestBaseClass))
{
    var instance = Activator.CreateInstance(type);

    foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
    {
       var value = prop.GetValue(instance);
    }
}