基于泛型+反射的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;
    }
相关推荐
棪燊20 小时前
Unity的Game视图在Scale放大后无法拖动
unity·游戏引擎
weixin_423995001 天前
unity 团结开发小游戏,加载AssetBundles
unity·游戏引擎
cyr___1 天前
Unity教程(二十七)技能系统 黑洞技能(下)黑洞状态
学习·游戏·unity·游戏引擎
齐鲁大虾1 天前
新人编程语言选择指南
javascript·c++·python·c#
加号31 天前
【C#】 WebAPI 接口设计与实现指南
开发语言·c#
张老师带你学1 天前
Unity 科幻武器系列
科技·游戏·unity·模型·游戏美术
unicrom_深圳市由你创科技1 天前
上位机开发常用的语言 / 框架有哪些?
c++·python·c#
平行云1 天前
虚拟直播混合式2D/3D应用程序实时云渲染推流解决方案
linux·unity·云原生·ue5·图形渲染·实时云渲染·像素流送
cyr___1 天前
Unity教程(二十六)技能系统 黑洞技能(上)基础实现
学习·游戏·unity·游戏引擎
xiaoshuaishuai81 天前
C# ZLibrary数字资源分发
开发语言·windows·c#