You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#嵌套类反射获取属性值遇报错,求无需switch的优化方案

无硬编码遍历嵌套类成员的解决方案

首先解决prop_Inner.GetValue(val_Outer)报错的核心问题:嵌套类实例未初始化。如果你的嵌套类属性/字段没有提前创建实例,调用GetValue会返回null,后续操作必然报错。先确保所有嵌套类成员在外部类中完成初始化(比如属性初始化器、构造函数中实例化)。

以下是无需硬编码判断类型的通用反射遍历实现,支持任意层级的嵌套类:

示例结构(模拟你的Preferences类)

public class Preferences
{
    // 初始化嵌套类实例,避免GetValue返回null
    public FunctionClass Function { get; set; } = new FunctionClass();
    public LoggerClass Logger { get; set; } = new LoggerClass();

    public class FunctionClass
    {
        public bool EnableAutoSave { get; set; } = true;
        public int Timeout { get; set; } = 3000;
        // 支持深层嵌套
        public AdvancedSettings Advanced { get; set; } = new AdvancedSettings();

        public class AdvancedSettings
        {
            public bool EnableHotkey { get; set; } = false;
            public string HotkeyCombo { get; set; } = "Ctrl+Shift+S";
        }
    }

    public class LoggerClass
    {
        public string LogPath { get; set; } = @"C:\Logs";
        public bool EnableDebugLog { get; set; } = false;
    }
}

通用遍历方法

using System;
using System.Reflection;
using System.Linq;

public static class ReflectionHelper
{
    public static void TraverseNestedClassMembers(object outerInstance)
    {
        if (outerInstance == null)
            return;

        Type currentType = outerInstance.GetType();
        // 获取当前类的所有公开实例成员(属性),筛选出属于当前类定义的嵌套类
        var nestedClassMembers = currentType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(member => member.PropertyType.IsClass 
                             && member.PropertyType.DeclaringType == currentType);

        foreach (var member in nestedClassMembers)
        {
            object nestedInstance = member.GetValue(outerInstance);
            if (nestedInstance == null)
            {
                Console.WriteLine($"[跳过] 嵌套类 {member.PropertyType.Name} 未初始化");
                continue;
            }

            Console.WriteLine($"\n=== 嵌套类 {member.PropertyType.Name} 的成员 ===");
            // 遍历嵌套类的所有公开实例属性
            var nestedProperties = nestedInstance.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var prop in nestedProperties)
            {
                object value = prop.GetValue(nestedInstance);
                Console.WriteLine($"{prop.Name}: {value ?? "null"}");
            }

            // 递归处理深层嵌套类
            TraverseNestedClassMembers(nestedInstance);
        }
    }
}

调用方式

var preferences = new Preferences();
ReflectionHelper.TraverseNestedClassMembers(preferences);

关键说明

  1. 避免GetValue报错:必须确保嵌套类实例已初始化(如示例中用= new XXX()),否则会触发null引用问题,方法中已加入null判断做容错处理。
  2. 精准筛选嵌套类:通过member.PropertyType.DeclaringType == currentType确保只处理当前类定义的嵌套类,不会误遍历其他引用类型属性(如string、List等)。
  3. 支持深层嵌套:方法通过递归自动处理多层嵌套的类结构,新增嵌套类无需修改遍历代码。
  4. 灵活扩展:如果需要遍历私有成员,只需修改BindingFlags为BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance即可。
  5. 替代硬编码switch:无需针对每个嵌套类写case判断,新增嵌套类后代码自动适配,符合开闭原则,扩展性更强。

内容的提问来源于stack exchange,提问作者Patrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 01:01:51