请问如何在.NET中通过字符串变量访问实例化类顶层成员(类似配置值访问)
实现字符串变量访问已实例化类顶层成员的方法
你现在使用的configuration[字符串键]访问配置值的逻辑,本质是基于键值匹配的索引器封装。要把完全一致的访问体验复刻到普通已实例化类的顶层成员上,有两种成熟的实现路径:
方法1:给目标类自定义索引器(最贴合配置系统的使用体验)
这种方式不需要依赖额外的反射逻辑,访问语法和你现在操作配置的写法完全统一:
- 给需要访问的目标类添加带字符串参数的索引器,在索引器内部手动映射字符串键和类的实际成员
- 匹配逻辑可以自行定制(比如忽略大小写、兼容不同命名风格),行为可以完全对齐.NET配置系统
示例代码:
// 待访问的目标业务类 public class RuntimeState { // 类的顶层公共成员,和你appsettings里的配置项一一对应 public string ConfigKey { get; set; } = "SomeConfigValue"; public int MaxRetryTimes { get; set; } = 3; // 复刻配置系统的索引器访问能力 public object this[string memberName] { get { // 匹配逻辑可以按需调整:比如忽略大小写、匹配蛇形/驼峰命名差异 return memberName switch { nameof(ConfigKey) => ConfigKey, nameof(MaxRetryTimes) => MaxRetryTimes, _ => null // 未匹配到成员时返回null,和配置系统的默认行为一致 }; } set { switch (memberName) { case nameof(ConfigKey): ConfigKey = (string)value; break; case nameof(MaxRetryTimes): MaxRetryTimes = (int)value; break; } } } }
使用时的写法和访问配置完全一致:
// 实例化目标类 var stateInstance = new RuntimeState(); var targetKey = "ConfigKey"; // 用字符串变量直接访问成员值 var memberValue = stateInstance[targetKey]; Console.WriteLine(memberValue); // 输出结果和访问配置时的逻辑完全相同
方法2:通用反射扩展方法(适配任意已实例化的类)
如果需要给多个不同的业务类实现这种访问能力,不需要逐个手写索引器,可以封装一套基于反射的通用扩展方法,对所有类生效:
public static class InstanceAccessor { // 扩展方法:基于字符串取实例的公共属性值 public static object GetMemberValue(this object instance, string memberName) { var memberInfo = instance.GetType() .GetProperty( name: memberName, bindingAttr: BindingFlags.Public | BindingFlags.Instance, binder: null, returnType: null, types: Type.EmptyTypes, modifiers: null ); // 匹配不到成员时返回null,对齐配置系统行为 return memberInfo?.GetValue(instance); } // 扩展方法:基于字符串设置实例的公共属性值 public static void SetMemberValue(this object instance, string memberName, object value) { var memberInfo = instance.GetType() .GetProperty(memberName, BindingFlags.Public | BindingFlags.Instance); if (memberInfo is { CanWrite: true }) { memberInfo.SetValue(instance, value); } } }
使用时不需要修改原有业务类的代码,任意已实例化的对象都可以直接用字符串访问:
// 随便一个已实例化的业务类 var businessInstance = new OrderService { ConfigKey = "SomeConfigValue" }; var targetKey = "ConfigKey"; // 直接通过扩展方法用字符串取值 var value = businessInstance.GetMemberValue(targetKey);
行为对齐小提示
- 可以在反射匹配时加上
ignoreCase: true参数,实现和配置系统一样的大小写不敏感访问 - 如果需要支持类似配置系统的嵌套键路径(比如
"Parent:Child"格式的键),只需要在取值逻辑里按冒号拆分路径、逐层访问嵌套成员即可,完全可以复刻配置系统的全量访问能力
内容的提问来源于stack exchange,提问作者Cliff Crerar
相关产品推荐
相关产品推荐

