基于泛型+反射的Excel万能导表工具

问题描述

  1. Excel的第一行记录字段名;
  2. 我们给这个函数输入一个泛型参数TConfig,可以让所有配置继承一个基类,拿这个基类约束一下;
  3. new Dictionary<string,TConfig>。如果导出SO,不能显示字典,就new List<TConfig>;
  4. 我们要在Excel列和TConfig字段之间建立一个关系,这个复杂度取决于你是通过字段名匹配还是顺序匹配。我们希望这个关系建立后,遍历行时可以很快的知道这一格数据要填入哪个字段。如果通过字段名匹配,读取Excel第一行每一列,查fieldDic,查到了,看字段类型,string就直接ToString,int、float、bool就tryParse。
  5. 然后要得到这个字段要转换成的类型,可以从Excel得到,也可以反射从typeof(TConfig)得到。GetFields得到TConfig的所有字段,生成一个字段名为键的字典fieldDic;
  6. 难以处理的是枚举。从fieldInfo应该是能得到具体枚举类型的。好的现在我们需要一个函数,它接受一个FieldInfo,一个字符串,如果这个FieldInfo是枚举,而且字符串是枚举的选项之一,则返回那一种枚举的那一个选项(做到的吗?)
  7. 然后还有/分隔的string、int、float、bool、枚举。在类里这会是一个List,如果用反射要先判断fieldInfo是List,再判断元素类型;
  8. 然后还有/分隔的字符串*int(比如怪物掉落多种道具、合成道具需要多种原料的数量),这种在类里会是一个字典......;
  9. 让一个函数用循环+判断处理以上所有情况......我放弃了。

把字符串尝试转换成枚举选项:

cs 复制代码
using System;
using System.Reflection;

public static class EnumFieldHelper
{
    /// <summary>
    /// 检查字段是否为枚举类型,并将字符串转换为对应的枚举值
    /// </summary>
    /// <param name="fieldType">字段的Type(FieldInfo.FieldType)</param>
    /// <param name="enumStr">要转换的枚举字符串(支持枚举名/枚举值数字)</param>
    /// <param name="enumValue">转换成功的枚举值(失败时为默认值)</param>
    /// <returns>true=转换成功,false=转换失败(非枚举/字符串不匹配)</returns>
    public static bool TryParseEnumFromFieldType(Type fieldType, string enumStr, out object enumValue)
    {
        // 初始化返回值为默认
        enumValue = null;

        // 1. 空值校验
        if (fieldType == null)
        {
            Console.WriteLine("错误:fieldType 不能为null");
            return false;
        }
        if (string.IsNullOrWhiteSpace(enumStr))
        {
            Console.WriteLine("错误:枚举字符串不能为空");
            return false;
        }

        // 2. 判断字段是否为枚举类型
        if (!fieldType.IsEnum)
        {
            Console.WriteLine($"错误:字段类型 {fieldType.Name} 不是枚举类型");
            return false;
        }

        try
        {
            // 3. 尝试将字符串转换为枚举(支持枚举名/数字字符串,忽略大小写)
            enumValue = Enum.Parse(fieldType, enumStr, ignoreCase: true);
            
            // 4. 二次校验:确保转换后的值是枚举的有效选项(防止数字超出枚举范围)
            if (Enum.IsDefined(fieldType, enumValue))
            {
                return true;
            }
            else
            {
                Console.WriteLine($"错误:字符串 {enumStr} 对应的数值不是 {fieldType.Name} 枚举的有效选项");
                enumValue = null;
                return false;
            }
        }
        catch (ArgumentException)
        {
            Console.WriteLine($"错误:无法将字符串 {enumStr} 转换为枚举 {fieldType.Name}");
            return false;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"转换枚举时发生异常:{ex.Message}");
            return false;
        }
    }

    // 简化版:直接返回枚举值(失败返回null)
    public static object ParseEnumFromFieldType(Type fieldType, string enumStr)
    {
        TryParseEnumFromFieldType(fieldType, enumStr, out object enumValue);
        return enumValue;
    }
}

生成字段字典

cs 复制代码
static Dictionary<string, FieldInfo> GetFieldDictionary<TConfig>() where TConfig : ConfigBase
    {
        var fields = typeof(TConfig).GetFields(BindingFlags.Public | BindingFlags.Instance);
        var fieldDic = new Dictionary<string, FieldInfo>();
        foreach (var field in fields)
        {
            var attr = field.GetCustomAttribute<ExcelFieldAttribute>();
            var name = attr?.Name ?? field.Name;
            fieldDic[name] = field;
        }
        return fieldDic;
    }
相关推荐
scott.cgi3 小时前
Unity直接编译Java文件作为插件,导致失败的两个打包设置
java·unity·unity调用java·unity的java文件·unity的android插件·unity调用android·unity加载java代码
qq_4312807012 小时前
上位与基恩士PLC通讯工作记录
c#
weixin_4280053016 小时前
C#调用 AI学习从0开始-第1阶段(基础与工具)-第2天Prompt工程基础
人工智能·学习·c#·prompt
咩图17 小时前
WPF-VisualStudio-C#-Fluent.Ribbon8.0.0学习
c#·wpf·visual studio
游乐码18 小时前
Unity坦克案例疑难记录(一)
unity·单例模式
加号318 小时前
【C#】WPF基于Halcon 的HWindowControlWPF 控件实现图像缩放、移动
开发语言·c#·wpf
雪豹阿伟18 小时前
2.C# —— 结构体、类型转换与运算符
c#·上位机
小贺儿开发19 小时前
Unity3D 编辑器对象锁定工具
unity·编辑器·编程·工具·对象·互动·拓展
njsgcs20 小时前
c# solidworks GetPartBox无法获得正确实体边界框原因
开发语言·c#·solidworks
rockey62720 小时前
AScript之匿名类型与动态类型
c#·.net·script·eval·expression·动态脚本