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

C#如何动态指定对象字段,复用CSV写入函数?

解决动态访问Player属性写入CSV的问题

你遇到的核心问题是C#作为静态类型语言,无法直接通过字符串变量访问对象属性(playerarray[i].arg这种写法会被编译器识别为访问Player类的arg属性,而非你传入的字符串对应的目标属性)。下面提供两种实用解决思路:

方法1:使用反射实现动态属性访问

反射可在运行时获取类型信息,动态读取对象属性值。修改WriteSpecificPlayerInfo方法如下:

public static void WritePlayerInfo(Player[] playerArray, StreamWriter writer)
{
    WriteSpecificPlayerInfo(playerArray, writer, "Name");
    WriteSpecificPlayerInfo(playerArray, writer, "Class");
    // 其他字段...
}

public static void WriteSpecificPlayerInfo(Player[] playerArray, StreamWriter writer, string propertyName)
{
    // 获取Player类的指定属性
    var property = typeof(Player).GetProperty(propertyName);
    if (property == null)
    {
        throw new ArgumentException($"Player类不存在名为{propertyName}的属性");
    }

    for (int i = 0; i < playerArray.Length; i++)
    {
        // 动态获取属性值,空值转为空字符串
        var value = property.GetValue(playerArray[i])?.ToString() ?? string.Empty;
        if (i == playerArray.Length - 1)
        {
            writer.WriteLine(value);
        }
        else
        {
            writer.Write($"{value};");
        }
    }
}

注意:反射存在一定性能开销,处理大量数据时建议优先用方法2。

方法2:使用委托(Func<Player, object>)实现类型安全访问

通过委托传递属性访问逻辑,编译时即可验证属性存在性,性能比反射更优:

public static void WritePlayerInfo(Player[] playerArray, StreamWriter writer)
{
    WriteSpecificPlayerInfo(playerArray, writer, p => p.Name);
    WriteSpecificPlayerInfo(playerArray, writer, p => p.Class);
    // 其他字段...
}

public static void WriteSpecificPlayerInfo(Player[] playerArray, StreamWriter writer, Func<Player, object> propertyAccessor)
{
    // 用String.Join简化分隔符处理,避免循环内的条件判断
    var values = string.Join(";", playerArray.Select(p => propertyAccessor(p)?.ToString() ?? string.Empty));
    writer.WriteLine(values);
}

这种写法更简洁,还能提前规避属性不存在的运行时错误。

额外优化:生成标准CSV格式(可选)

如果需要生成每行对应一个Player、每列对应一个字段的标准CSV,可封装为一次性写入所有字段:

public static void WritePlayersToCsv(Player[] playerArray, StreamWriter writer, params Func<Player, object>[] propertyAccessors)
{
    // 写入表头(可选)
    var headers = propertyAccessors.Select(accessor => 
        accessor.Method.Name.Replace("get_", "")); // 从委托方法名提取属性名
    writer.WriteLine(string.Join(";", headers));

    // 写入每行数据
    foreach (var player in playerArray)
    {
        var values = string.Join(";", propertyAccessors.Select(accessor => 
            accessor(player)?.ToString() ?? string.Empty));
        writer.WriteLine(values);
    }
}

// 调用示例
WritePlayersToCsv(playerArray, writer, p => p.Name, p => p.Class);

内容的提问来源于stack exchange,提问作者Lolipop

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:00:24