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