You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

These are the models

需求描述

我拥有若干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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:46:13