类构造函数初始化paramsGroup字段触发异常的技术求助
构造函数初始化参数列表触发异常,寻求动态参数有序存储方案
我开发了一个将方法归类到类中的应用,用户按下对应按键会触发类内方法,这部分运行正常。但添加名为paramsGroup的List<object>字段(用于存储方法调用所需参数)后,在FileManager类构造函数初始化该列表的位置触发异常。
异常相关代码片段
FileManager类构造函数(异常触发位置)
/// <summary> Performs the Functions related to the File Manager of this Program. </summary> internal class FileManager : Framework { /// <summary> Creates a new Instance of the FileManager. </summary> public FileManager() { this.ID = 1; this.name = Text.LocateByID(Interface.stringsList, "FRAMEWORK_FILE_MANAGER"); this.paramsGroup = new List<object>() // 构造函数中触发异常的位置 { // Param #0 - Input Path Loader.LocateResource<InputPathDialog>(Interface.dialogs).Display(), // Param #1 - Output Path Loader.LocateResource<OutputPathDialog>(Interface.dialogs).Display(), // Param #2 - New Name Loader.LocateResource<NewNameDialog>(Interface.dialogs).Display() }; // 剩余代码片段... } }
Loader类的LocateResource方法
/// <summary> Locates a Resource from a Dictionary with the Specific Type. </summary> /// <param name = "sourceDictionary" > The Dictionary to be Filtered. </param> /// <returns> The Instance of the Resource obtained. </returns> public static T LocateResource<T>(Dictionary<string, object> sourceDictionary) { Type resourceType = typeof(T); return (T)sourceDictionary[resourceType.Name]; }
参数使用场景(方法重载调用)
this.functionsList = new List<Function>() { // Function A - Display File Properties new Function() { ID = ConsoleKey.A, name = Text.LocateByID(Interface.stringsList, "FUNCTION_DISPLAY_FILE_PROPERTIES"), process = Task_Manager.CreateTask( () => Archive_Manager.DisplayFileProperties(paramsGroup[0] as string) ) // 从paramsGroup获取第一个元素并转为string } };
前置说明与排查尝试
Interface.dialogs字典初始化逻辑:筛选程序集内指定命名空间的类型,通过Activator.CreateInstance创建实例,以类型名为键存入字典。- 排查过的尝试:
- 修改
paramsGroup访问修饰符(从protected改为public),问题依旧 - 将字段类型从
List<object>改为object[],结果相同
- 修改
需求
需要一种有序存储参数的方式,参数可能随用户选择动态变化,方便后续方法调用时随时获取。
异常原因分析与解决方案
1. 构造函数阶段过早调用交互方法
构造函数中直接调用Display()会在类实例化时立即弹出对话框,可能触发线程模型冲突(比如UI/控制台程序的线程限制),或者Interface.dialogs中的实例尚未完成初始化。
解决办法:延迟参数获取
先存储对话框实例,在需要参数时再调用Display():
// 存储对话框实例而非直接调用Display() private List<object> _dialogInstances; public FileManager() { this.ID = 1; this.name = Text.LocateByID(Interface.stringsList, "FRAMEWORK_FILE_MANAGER"); _dialogInstances = new List<object>() { Loader.LocateResource<InputPathDialog>(Interface.dialogs), Loader.LocateResource<OutputPathDialog>(Interface.dialogs), Loader.LocateResource<NewNameDialog>(Interface.dialogs) }; } // 按需获取参数 private string GetInputPath() => (_dialogInstances[0] as InputPathDialog).Display(); // 方法调用时使用 process = Task_Manager.CreateTask(() => Archive_Manager.DisplayFileProperties(GetInputPath()));
2. 字典键名不匹配导致KeyNotFoundException
Loader.LocateResource用typeof(T).Name作为键,但如果Interface.dialogs的键是完整类型名(含命名空间),会触发键不存在异常。
解决办法:统一键名生成逻辑
如果字典用完整类型名作为键,修改Loader方法:
public static T LocateResource<T>(Dictionary<string, object> sourceDictionary) { Type resourceType = typeof(T); return (T)sourceDictionary[resourceType.FullName]; }
3. 类型转换失败引发InvalidCastException
如果Interface.dialogs中的实例不是目标泛型类型,强制转换会触发异常。
解决办法:添加类型校验
public static T LocateResource<T>(Dictionary<string, object> sourceDictionary) { Type resourceType = typeof(T); if (sourceDictionary.TryGetValue(resourceType.Name, out var obj)) { if (obj is T tInstance) { return tInstance; } throw new InvalidCastException($"对象 {resourceType.Name} 无法转换为 {typeof(T).FullName}"); } throw new KeyNotFoundException($"字典中未找到资源 {resourceType.Name}"); }
4. 更灵活的参数存储方案
如果参数需动态变化,推荐用延迟加载+字典映射替代固定索引列表,可读性与扩展性更强:
// 存储参数获取逻辑,键为参数标识 private Dictionary<string, Func<object>> _parameterProviders = new(); public FileManager() { _parameterProviders.Add("InputPath", () => Loader.LocateResource<InputPathDialog>(Interface.dialogs).Display()); _parameterProviders.Add("OutputPath", () => Loader.LocateResource<OutputPathDialog>(Interface.dialogs).Display()); _parameterProviders.Add("NewName", () => Loader.LocateResource<NewNameDialog>(Interface.dialogs).Display()); } // 调用时直接按标识获取 process = Task_Manager.CreateTask(() => Archive_Manager.DisplayFileProperties(_parameterProviders["InputPath"]() as string));
内容的提问来源于stack exchange,提问作者user22209379
相关产品推荐
相关产品推荐

