如何通用处理object存储的List<T>,实现日志参数统一遍历
泛型列表日志处理的通用适配方案
报错根因
原有代码强行将泛型列表对象转为List<object>,但C#中具体泛型类型(比如List<SqlParameter>、List<int>)与List<object>不存在隐式或显式的继承转换关系,直接强转必然触发类型转换失败。
且当前场景仅需要遍历集合元素、调用ToString拼接日志文本,完全不需要感知元素的具体强类型,因此不需要为每一种可能的泛型集合单独编写适配规则。
通用实现思路
所有泛型集合(包括List<T>、数组、HashSet<T>等)都实现了非泛型的System.Collections.IEnumerable接口,通过判断对象是否实现该接口,即可统一拿到所有可遍历集合的迭代器,不需要绑定具体的泛型类型。
注意:字符串类型本身也实现了IEnumerable<char>,需要在判断时单独排除,否则会被错误拆分为单个字符遍历输出。
修正后的代码实现
public static string LogParameters(params object[] parameters) { string returnValue = "\n"; if (parameters == null) { return returnValue; } for (int i = 0; i < parameters.Length; i++) { var currentParam = parameters[i]; if (currentParam == null) { returnValue += "---->null null\n"; continue; } // 单独处理字符串,避免被枚举拆分 if (currentParam is string strValue) { returnValue += GetLogParameterTypeText(strValue); continue; } // 统一处理所有可枚举集合(泛型List、数组、自定义集合等) if (currentParam is System.Collections.IEnumerable enumerableValue) { returnValue += GetLogParameterTypeText(currentParam); foreach (var item in enumerableValue) { returnValue += GetLogParameterTypeText(item, "----"); } continue; } // 普通值类型、非集合引用类型按原有逻辑处理 returnValue += GetLogParameterTypeText(currentParam); } return returnValue; }
方案特点
- 完全不需要为具体的泛型集合类型(比如
List<SqlParameter>)单独编写适配规则,所有实现IEnumerable的集合类型都可以被自动识别处理 - 合并了原有代码中数组、泛型列表两套几乎完全重复的遍历逻辑,减少冗余代码和维护成本
- 完全匹配场景需求:遍历过程中不需要对元素做强类型转换,仅需要将元素传入现有日志格式化方法拼接文本即可
- 保留了原有的非集合类型处理逻辑,不影响原有普通参数的日志输出效果
可选扩展:如果后续需要专门优化字典类型(如
Dictionary<TKey,TValue>)的日志展示效果,可以在枚举判断前新增IDictionary类型的判断分支,自定义键值对的输出格式。
内容的提问来源于stack exchange,提问作者Tim F
相关产品推荐
相关产品推荐

