C#如何实现支持参数访问的Options属性(非Indexer实现)
实现方法
C# 本身不支持直接定义带方括号参数的属性,你要实现inv.Options["Key"]的调用形式,只需要把Options定义为自带索引器的自定义类型实例即可,外层Inventory类仅暴露该类型的只读属性,内部逻辑直接对接你的私有字典存储。
完整实现代码
public class Inventory { // 内部存储配置的私有字典,不对外暴露 private readonly Dictionary<string, object> _optionsStorage = new Dictionary<string, object>(); // 对外暴露的Options访问入口 public InventoryOptions Options { get; } public Inventory() { // 初始化Options时传入内部私有字典的引用,所有读写操作直接操作原存储 Options = new InventoryOptions(_optionsStorage); } // 嵌套定义Options的专用类型,避免污染外部命名空间 public class InventoryOptions { private readonly Dictionary<string, object> _underlyingStorage; // 构造函数标记为internal,外部代码无法随意实例化该类型,只能通过Inventory的Options属性访问 internal InventoryOptions(Dictionary<string, object> underlyingStorage) { _underlyingStorage = underlyingStorage; } // 定义索引器,匹配["xxx"]的读写语法 public object this[string optionKey] { get { _underlyingStorage.TryGetValue(optionKey, out var value); return value; } set => _underlyingStorage[optionKey] = value; } } }
调用验证
上述代码完全匹配你预期的使用方式:
Inventory inv = new Inventory(); // 读值,因为存储类型是object,值类型需要显式强转 string invLabel = (string)inv.Options["Label"]; inv.Options["Size"] = 10; int size = (int)inv.Options["Size"]; // 写值 inv.Options["Weight"] = 24;
方案说明
- 该实现和直接给
Inventory类定义索引器有本质区别,调用入口必须经过Options属性,不会出现inv["Size"]的调用形式,完全符合你的需求 - 所有读写操作最终都直接作用于
Inventory的私有字典,没有额外的数据拷贝,性能和直接操作字典一致 - 不推荐直接把
Options属性类型定义为Dictionary<string, object>:这种写法会把字典的Clear、Remove等所有方法暴露给外部,很容易破坏内部逻辑,自定义嵌套类型可以完全控制对外的读写权限,后续如果要加参数校验、默认值、变更通知等逻辑也可以直接在索引器里扩展。
内容的提问来源于stack exchange,提问作者FLICKER
相关产品推荐
相关产品推荐

