C#如何动态为不同数据类型变量填充AppConfig配置值
核心问题说明
你当前的写法存在两个本质问题,导致无法完成预期赋值:
- 循环中的迭代变量
val只是配置键名的局部字符串副本,修改它的值完全不会影响循环外定义的port、useCredentials等独立变量 - AppSettings读取到的所有原始值都是字符串格式,没有针对不同字段的类型做校验和转换,直接赋值会出现类型不匹配的运行时错误
实现方案
不需要写一堆重复的if判断,也不需要用复杂的反射逻辑,只需要把每个配置项的键名、对应赋值/类型转换逻辑统一存在元数据列表里,一次遍历就能完成空值校验、类型转换、字段赋值全流程。
注意:使用
ConfigurationManager需要先给项目添加System.Configuration程序集引用,否则会报找不到类型的编译错误。
完整实现代码如下:
using System; using System.Collections.Generic; using System.Configuration; // 预先定义需要赋值的强类型变量 string smtpServer = ""; int port = 0; bool useCredentials = false; string username = ""; string password = ""; bool useSsl = false; string receiver = ""; string sender = ""; string subject = ""; string body = ""; bool hasConfigError = false; // 统一维护所有配置项的元数据:配置键名、对应类型转换+赋值逻辑 var configMapping = new List<(string Key, Action<string> SetValue)> { ("smtpServer", val => smtpServer = val), ("port", val => { if (!int.TryParse(val, out port)) { Console.WriteLine($"配置错误:port的值[{val}]不是合法整数"); hasConfigError = true; } }), ("useCredentials", val => { if (!bool.TryParse(val, out useCredentials)) { Console.WriteLine($"配置错误:useCredentials的值[{val}]不是合法布尔值(仅支持true/false)"); hasConfigError = true; } }), ("username", val => username = val), ("password", val => password = val), ("useSsl", val => { if (!bool.TryParse(val, out useSsl)) { Console.WriteLine($"配置错误:useSsl的值[{val}]不是合法布尔值(仅支持true/false)"); hasConfigError = true; } }), ("receiver", val => receiver = val), ("sender", val => sender = val), ("subject", val => subject = val), ("body", val => body = val) }; // 统一遍历完成所有配置的校验和赋值 foreach (var configItem in configMapping) { string rawValue = ConfigurationManager.AppSettings[configItem.Key]?.Trim(); if (string.IsNullOrEmpty(rawValue)) { Console.WriteLine($"配置错误:{configItem.Key}为空或不存在"); hasConfigError = true; continue; } configItem.SetValue(rawValue); Console.WriteLine($"配置加载成功:{configItem.Key} = {rawValue}"); } if (hasConfigError) { Console.WriteLine("配置加载终止,请检查App.config中的配置项后重试"); Environment.Exit(1); } // 后续逻辑可以直接使用所有完成类型转换、赋值的变量
这个方案的优势:
- 所有配置规则集中维护,后续新增、修改配置项只需要在
configMapping列表中加对应条目即可,不需要改动遍历校验的核心逻辑 - 类型转换错误会被单独捕获,给出明确的错误提示,不会因为配置格式错误直接抛出未处理异常
- 没有用反射等动态逻辑,性能和逐行手写校验赋值完全一致,没有额外开销
内容的提问来源于stack exchange,提问作者Steinimator
相关产品推荐
相关产品推荐

