基于泛型+反射的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;
    }
相关推荐
小曹要微笑3 小时前
C#什么是方法
c#·c#方法·方法是什么·什么是方法
阿蒙Amon3 小时前
C#常用类库-详解CsvHelper
开发语言·数据库·c#
军训猫猫头3 小时前
5.正弦波生成器:支持连续相位与可控重置 C# + WPF 完整示例
c#·.net·wpf
心前阳光4 小时前
Mirror网络库插件使用4
java·linux·网络·unity·c#·游戏引擎
城数派4 小时前
2005-2025年我国省市县三级的逐日地表温度数据(Shp/Excel格式)
数据分析·excel
格林威5 小时前
工业相机图像高速存储(C#版):先存内存,后批量转存方法,附海康相机实战代码!
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·海康相机
sanshizhang5 小时前
C#如何获取CAD的对象并修改
windows·c#·cad插件
小曹要微笑6 小时前
C#中什么是类
开发语言·c#·面向对象·