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