C# switch按类型匹配多类Dictionary时无法强转为Dictionary<object,object>
问题根因
Dictionary<TKey, TValue>不支持泛型协变,无法直接将Dictionary<int, string>、Dictionary<decimal, bool>这类具体泛型类型的字典强转为Dictionary<object, object>,强行强转会触发运行时类型转换异常。
这种转换被禁止是C#的类型安全机制决定的:如果允许上述强转,就可以通过
Dictionary<object,object>的引用向原字典插入不符合键/值类型约束的元素,直接破坏泛型集合的类型一致性。
另外你当前switch分支分别匹配两种具体字典类型的写法扩展性很差,后续新增其他键值类型的字典时需要不断新增case分支。
最优修复方案
你的字典处理方法仅做序列化日志输出,不需要修改字典内容,完全没必要限定入参为Dictionary<object,object>,直接使用所有泛型字典都实现的非泛型IDictionary接口作为入参即可,改动量最小,且自动兼容所有字典类型。
修复后完整可运行代码:
using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; static void Main(string[] args) { Dictionary<int, string> dict = new Dictionary<int, string> () { {1, "One"}, {2, "Two"} }; Dictionary<decimal, bool> dict2 = new Dictionary<decimal, bool> () { {1, true}, {2, false} }; Double doubleObj = 100.2; HandleLogging(doubleObj); HandleLogging(dict); HandleLogging(dict2); } private static void HandleLogging(Object obj) { switch (obj) { case double _: Console.WriteLine("Double data type .."); break; case IDictionary dict: // 直接匹配非泛型IDictionary接口,所有Dictionary<,>类型都会命中该分支 Console.WriteLine("Dictionary data type.."); HandleDictionary(dict); break; default: Console.WriteLine("unknown type"); break; } } // 入参改为非泛型IDictionary,兼容所有键值类型的字典 private static void HandleDictionary(IDictionary existingDictionary) { Console.WriteLine(string.Format("Dictionary object : {0}", JsonConvert.SerializeObject(existingDictionary))); }
兼容方案(无法修改HandleDictionary入参时使用)
如果因为业务逻辑限制,HandleDictionary必须接收Dictionary<object,object>类型入参,可以在分支内手动遍历原始字典的键值对,生成符合类型要求的新字典后传入:
case IDictionary dict: Console.WriteLine("Dictionary data type.."); Dictionary<object, object> convertedDict = new Dictionary<object, object>(); foreach (DictionaryEntry entry in dict) { convertedDict.Add(entry.Key, entry.Value); } HandleDictionary(convertedDict); break;
内容的提问来源于stack exchange,提问作者Naren K
相关产品推荐
相关产品推荐

