Как использовать отражение во вложенных классах для получения значений

У меня есть высший класс с вложенными классами

public class Preferences
{
    public FunctionClass function { get; set; } = new FunctionClass();
    public class FunctionClass
    {
        public string programfolder { get; set; } = "";
        ...
    }

    public LoggerClass logger { get; set; } = new LoggerClass();
    public class LoggerClass 
    {
        public string logFolder { get; set; } = "Log";
        ...
    }

    public OptionClass options { get; set; } = new OptionClass();
    public class OptionClass
    {
        public bool showGraphics { get; set; } = true;
        ...
    }

    public MqttSpSetupClass MqttSpSetup { get; set; } = new MqttSpSetupClass();
    public class MqttSpSetupClass
    {
        public string strAddress { get; set; } = "localhost";
        ...
    }
}

поэтому я хочу, чтобы отражение зацикливалось на всех членах каждого внутреннего класса

PropertyInfo[] props_Outer = typeof(IoAppPreferences).GetProperties();
int counter = 0;
foreach (PropertyInfo prop_Upper in props_Outer)
{
    var sName_Outer = prop_Upper.Name;
    var val_Outer = props_Outer.GetValue(counter ++);
        
    PropertyInfo[] properties_Inner;
    switch (sName_Outer.ToUpper())
    {
        case "DIMS": properties_Inner = typeof(IoAppPreferences.DimsClass).GetProperties(); break;
     ...    
    }

             
    foreach (PropertyInfo prop_Inner in properties_Inner)
    {
        var sName = prop_Inner.Name;
        //prefs.function

        var sVal = prop_Inner.GetValue(val_Outer);<------ERROR

        switch (prop_Inner.Name.ToUpper())
        {
         ...            
        }
    }

Я получаю сообщение об ошибке, где я поставил стрелку. И причина в том, что val_Outer является функцией FunctionClass, а если я жестко запрограммирую prefs.function, все в порядке. Конечно, я могу поставить переключатель на каждый из них, но мой вопрос: есть ли лучший способ решить эту проблему?

Я видел это решение, но оно не соответствует моим потребностям

Какая ошибка? ....

Selvin 16.02.2023 11:23

хе-хе, теперь я вижу это .. это Array.GetValue, что по-прежнему делает val_OuterPropertyInfo не значением свойства ... (если быть точным, теперь у вас есть val_Outer == prop_Upper)

Selvin 16.02.2023 11:28

Кроме того, почему вы используете отражения? это похоже на загрузку некоторых настроек/настроек... как они хранятся? как json? почему бы вам просто не сгенерировать модель С# из json, а затем просто десериализовать их

Selvin 16.02.2023 11:37

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

Patrick 16.02.2023 14:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы получили ошибку, потому что val_Outer — неправильный экземпляр. Вы пытаетесь получить значение из целого числа счетчика props_Outer.GetValue(counter ++)

Если ваша цель — получить значения свойств из вложенных классов, у вас должен быть экземпляр объекта Preferences:

    var appPreferences = new Preferences();
    var propsOuter = appPreferences.GetType().GetProperties();

    foreach (var po in propsOuter)
    {
        var valueOuter = po.GetValue(appPreferences);
        Console.WriteLine($"{po.Name}");

        if (valueOuter == null) continue;

        var propsInner = valueOuter.GetType().GetProperties();
        foreach (var pi in propsInner)
        {
            var valueInner = pi.GetValue(valueOuter);
            Console.WriteLine($"{pi.Name}: {valueInner}");
        }
    }

Но получение значений через отражение практически бесполезно, если у вас уже есть экземпляр объекта.

Другие вопросы по теме