如何创建通用函数适配多个Model类实现文本文件转换?

需求描述
我拥有若干Model类(如personModel、teamModel等,均位于model命名空间下),希望创建一个通用函数来处理这些Model类,实现文本文件转换功能。
目前我已有针对PrizeModel的转换函数(代码如下),但不想为每个Model单独编写函数,想学习如何实现一个通用函数。
public static List<PrizeModel> ConvertToPrizeModel(this List<string> lines) { List<PrizeModel> output = new List<PrizeModel>(); foreach (string line in lines) { string[] cols = line.Split(','); PrizeModel p = new PrizeModel(); p.Id = int.Parse(cols[0]); p.PlaceNumber = int.Parse(cols[1]); p.PlaceName = cols[2]; p.PrizeAmount = decimal.Parse(cols[3]); p.PrizePercentage = double.Parse(cols[4]); output.Add(p); } return output; }
方案一:泛型+委托(灵活可控,适合学习阶段)
这种方式用泛型搭建通用框架,让调用者传入「每行字符串转对应Model」的逻辑,既保留通用性,又保证类型安全。
通用函数代码
public static List<T> ConvertToModel<T>(this List<string> lines, Func<string[], T> lineToModelConverter) { List<T> output = new List<T>(); foreach (string line in lines) { string[] cols = line.Split(','); T model = lineToModelConverter(cols); output.Add(model); } return output; }
调用示例
// 转换PrizeModel List<PrizeModel> prizeModels = lines.ConvertToModel(cols => new PrizeModel { Id = int.Parse(cols[0]), PlaceNumber = int.Parse(cols[1]), PlaceName = cols[2], PrizeAmount = decimal.Parse(cols[3]), PrizePercentage = double.Parse(cols[4]) }); // 转换personModel List<personModel> personModels = lines.ConvertToModel(cols => new personModel { Id = int.Parse(cols[0]), Name = cols[1], Age = int.Parse(cols[2]) });
优点
- 编译时就能检查类型错误,安全可靠
- 每个Model的转换逻辑清晰直观
- 无额外依赖,适合基础阶段理解泛型和委托的用法
方案二:反射(完全通用,注意性能)
如果想做到完全自动映射,无需手动写转换逻辑,可以用反射读取Model的属性,自动完成字符串到对应类型的转换。
通用函数代码
public static List<T> ConvertToModelWithReflection<T>(this List<string> lines) where T : new() { List<T> output = new List<T>(); // 获取当前Model的所有公共属性 var properties = typeof(T).GetProperties(); foreach (string line in lines) { string[] cols = line.Split(','); T model = new T(); for (int i = 0; i < properties.Length && i < cols.Length; i++) { var property = properties[i]; string value = cols[i].Trim(); // 将字符串转换为属性对应的类型 object convertedValue = Convert.ChangeType(value, property.PropertyType); property.SetValue(model, convertedValue); } output.Add(model); } return output; }
调用示例
// 转换PrizeModel List<PrizeModel> prizeModels = lines.ConvertToModelWithReflection<PrizeModel>(); // 转换personModel List<personModel> personModels = lines.ConvertToModelWithReflection<personModel>();
注意事项
- Model类必须有无参构造函数(所以加了
where T : new()约束) - 分割后的列顺序必须和Model属性的定义顺序完全一致
- 字符串要能被正确转换为属性类型(比如数字字符串不能包含非数字字符)
- 反射性能比委托方式差,适合小数据量场景
总结
学习阶段优先掌握方案一,它能帮你理解泛型和委托的核心用法;如果追求极致通用,可以尝试方案二,但要清楚反射的优缺点。
内容的提问来源于stack exchange,提问作者user21952045
相关产品推荐
相关产品推荐

