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

C#多类型用户输入层级存储的类型安全数据结构选型咨询

请提供需要使用Markdown格式化的具体内容,以下是按你指定规则的格式示例:

一级标题

二级标题

  • 无序列表项1
  • 无序列表项2

这是强调的文本

Console.WriteLine("Hello World");

这是一段引用的文本

链接显示文本

图片替代文本


若你需要格式化的是之前的C#层级化输入存储问题,以下是格式化后的完整内容及解决方案:

C#层级化用户输入存储方案咨询

我正在开发一款C#应用,需存储大量不同类型(字符串、双精度浮点数、布尔值)的用户输入,且输入需按层级(类别、子类别等)组织,所有输入值均被封装在InputProperty<T>类中,该类存储实际值及附加数据。

层级结构示例:

Input data
-catA
--catAA
---propAAA
---propAAB
--catAB
---catABA
----propABAA
---propABA
-catB
--propBA
-catC
--catCA
---catCAA
----propCAAA

每个类别可包含子类别、输入属性或两者兼具。核心需求如下:

  • 支持类型安全地访问任意类别或属性,例如inputData.catA.catAA.propAAA,IDE可提前提示不存在的类别/属性;
  • 可获取某类别及其所有子类别中的全部属性,例如调用catA.GetAllProperties()返回包含propAAA、propAAB、propABAA、propABA的列表;
  • 可轻松进行序列化/反序列化及深拷贝操作。

我已考虑两种方案:

  1. 为每个类别创建唯一类,继承提供GetAllProperties功能的接口和基类,子类别与输入属性作为类字段。该方案满足需求1、2,但序列化/反序列化、深拷贝实现复杂,且需编写大量重复类,代码冗余;
  2. 使用单一类别类,通过subcategories和inputProperties字典构建层级。该方案满足需求2、3,但无法实现类型安全访问,需通过字符串索引导航,IDE无法提前报错,且C#无原生字符串枚举支持,需临时方案,并非最优解。

恳请推荐更优解决方案。


推荐解决方案:代码生成+基类组合模式

方案思路

结合代码生成自动创建类型安全的类别类,同时让每个类别类继承同一个提供通用功能的基类,兼顾类型安全、层级遍历、序列化三大需求。

具体实现步骤

  1. 定义通用基类
    创建一个抽象基类CategoryBase,内置GetAllProperties()方法用于递归遍历所有子类别属性,同时实现序列化特性与深拷贝方法:

    public abstract class CategoryBase
    {
        private readonly List<CategoryBase> _subCategories = new();
        private readonly List<object> _properties = new();
    
        protected void RegisterSubCategory(CategoryBase subCategory)
        {
            _subCategories.Add(subCategory);
        }
    
        protected void RegisterProperty(object property)
        {
            _properties.Add(property);
        }
    
        public IEnumerable<InputProperty<object>> GetAllProperties()
        {
            var result = new List<InputProperty<object>>();
            // 添加当前类别的属性
            result.AddRange(_properties.Cast<InputProperty<object>>());
            // 递归添加子类别属性
            foreach (var subCat in _subCategories)
            {
                result.AddRange(subCat.GetAllProperties());
            }
            return result;
        }
    
        // 基于序列化实现深拷贝
        public virtual T DeepCopy<T>() where T : CategoryBase
        {
            var json = System.Text.Json.JsonSerializer.Serialize(this);
            return System.Text.Json.JsonSerializer.Deserialize<T>(json);
        }
    }
    
  2. 编写代码生成模板
    使用T4模板或Roslyn代码生成工具,根据层级结构配置文件(如JSON/YAML)自动生成强类型类别类。例如针对catA和catAA生成的代码:

    public class CatA : CategoryBase
    {
        public CatAA CatAA { get; }
        public CatAB CatAB { get; }
    
        public CatA()
        {
            CatAA = new CatAA();
            RegisterSubCategory(CatAA);
            CatAB = new CatAB();
            RegisterSubCategory(CatAB);
        }
    }
    
    public class CatAA : CategoryBase
    {
        public InputProperty<string> PropAAA { get; }
        public InputProperty<double> PropAAB { get; }
    
        public CatAA()
        {
            PropAAA = new InputProperty<string>();
            RegisterProperty(PropAAA);
            PropAAB = new InputProperty<double>();
            RegisterProperty(PropAAB);
        }
    }
    
  3. 使用方式
    生成代码后即可实现类型安全访问、属性遍历与深拷贝:

    var inputData = new InputData();
    // IDE智能提示属性与类别
    inputData.CatA.CatAA.PropAAA.Value = "Test";
    // 获取catA下所有属性
    var allProps = inputData.CatA.GetAllProperties();
    // 深拷贝catA
    var clonedCatA = inputData.CatA.DeepCopy<CatA>();
    

方案优势

  • 类型安全:自动生成的强类型类支持IDE智能提示,编译时即可检测错误;
  • 低冗余:修改层级结构只需更新配置文件,重新生成代码即可;
  • 通用能力:基类内置遍历、序列化、深拷贝逻辑,无需重复编写;
  • 高性能:代码生成的强类型访问比反射或字典索引效率更高。

轻量化替代方案:嵌套记录+反射工具

若不想用代码生成,可定义嵌套记录类型,搭配反射工具实现属性遍历:

public record InputData(CatA CatA, CatB CatB, CatC CatC);
public record CatA(CatAA CatAA, CatAB CatAB);
public record CatAA(InputProperty<string> PropAAA, InputProperty<double> PropAAB);
// ...其他嵌套记录类

// 反射工具类实现遍历
public static class CategoryHelper
{
    public static IEnumerable<InputProperty<object>> GetAllProperties(object category)
    {
        var props = new List<InputProperty<object>>();
        foreach (var prop in category.GetType().GetProperties())
        {
            var value = prop.GetValue(category);
            if (value is InputProperty<object> inputProp)
            {
                props.Add(inputProp);
            }
            else if (value != null && !prop.PropertyType.IsValueType && prop.PropertyType != typeof(string))
            {
                props.AddRange(GetAllProperties(value));
            }
        }
        return props;
    }
}

该方案无需代码生成,但反射遍历性能略低,适合层级结构不频繁变更的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:14:51