如何构建语法简洁且支持IntelliSense的深度嵌套字典?
自定义寄存器容器类实现简洁嵌套访问
针对你需要动态构建嵌套寄存器结构、同时用简洁语法访问值的需求,推荐使用自定义支持索引器的容器类,既解决原Register类的语法繁琐问题,又避免Dictionary<string, object>的类型模糊问题。
核心实现代码
public class RegisterContainer { private readonly Dictionary<string, RegisterContainer> _subNodes = new(); private string? _leafValue; // 判断当前节点是分支(含子节点)还是叶子(存值) public bool IsLeaf => _leafValue != null; // 索引器:直接通过键访问子节点,实现链式索引 public RegisterContainer this[string key] { get => _subNodes[key]; set => _subNodes[key] = value; } // 隐式转换:叶子节点直接转成字符串,无需额外属性调用 public static implicit operator string(RegisterContainer container) { if (!container.IsLeaf) throw new InvalidOperationException("该节点是分支节点,无法直接取值"); return container._leafValue!; } // 快速创建叶子节点(存储具体值) public static RegisterContainer CreateLeaf(string value) { return new RegisterContainer { _leafValue = value }; } // 快速创建分支节点(包含子节点) public static RegisterContainer CreateBranch() { return new RegisterContainer(); } }
使用示例
// 构建嵌套寄存器结构 var registers = RegisterContainer.CreateBranch(); // 逐层创建分支和叶子节点 registers["PositionRegister"] = RegisterContainer.CreateBranch(); registers["PositionRegister"]["CurrentPosition"] = RegisterContainer.CreateBranch(); registers["PositionRegister"]["CurrentPosition"]["X_Coordinate"] = RegisterContainer.CreateLeaf("150.7"); registers["PositionRegister"]["CurrentPosition"]["Y_Coordinate"] = RegisterContainer.CreateLeaf("320.1"); registers["MotionStatus"] = RegisterContainer.CreateLeaf("Running"); // 简洁访问嵌套值 string x = registers["PositionRegister"]["CurrentPosition"]["X_Coordinate"]; string status = registers["MotionStatus"]; Console.WriteLine($"X坐标:{x},运行状态:{status}");
方案优势
- 语法简洁:完全符合你想要的
Registers["A"]["B"]["C"]链式访问方式,无需反复调用subRegisters属性 - 类型安全:通过隐式转换到
string,编译时就能明确取值类型,避免object强制转换的麻烦 - 无冗余信息:节点名称仅作为字典键存在,不会像原Register类那样重复存储
name属性 - 动态适配:支持解析时动态构建任意深度的嵌套结构,完美适配ASCII文本的可变格式
解析ASCII文件的适配思路
解析文本时,可按以下逻辑动态构建容器:
- 拆分每行的路径和值(比如按
=分割) - 将路径按分隔符(比如
.)拆分为层级列表 - 从根节点开始,逐层创建分支节点,直到最后一个层级
- 在最后一个层级创建叶子节点存储值
伪代码示例:
RegisterContainer ParseAsciiFile(string filePath) { var root = RegisterContainer.CreateBranch(); foreach (var line in File.ReadAllLines(filePath)) { if (string.IsNullOrWhiteSpace(line)) continue; var split = line.Split('='); var pathParts = split[0].Split('.'); var value = split[1]; var currentNode = root; // 遍历路径,创建分支节点 for (int i = 0; i < pathParts.Length - 1; i++) { if (!currentNode._subNodes.ContainsKey(pathParts[i])) { currentNode[pathParts[i]] = RegisterContainer.CreateBranch(); } currentNode = currentNode[pathParts[i]]; } // 最后一层创建叶子节点 currentNode[pathParts[^1]] = RegisterContainer.CreateLeaf(value); } return root; }
内容的提问来源于stack exchange,提问作者BlueAure
相关产品推荐
相关产品推荐

