MethodInfo.Invoke传入Enum类型参数时调用失败问题求助
问题根因
抛出类型转换异常的核心原因是两个默认行为的冲突:
- 当把JSON反序列化为无强类型约束的
List(Of Object)时,Json.NET会将所有整数值默认解析为64位整数System.Int64,不会提前感知后续反射调用的目标参数类型做预转换 MethodInfo.Invoke执行参数匹配时仅支持极有限的自动类型转换,不支持直接将数字值类型转换为目标枚举类型,传入Int64类型的枚举值时就会触发类型不匹配错误。
通用解决方案
由于需要适配大量不同签名的方法,不需要为单个方法编写单独的参数转换逻辑,只需在反射调用前,根据目标方法的参数定义自动将反序列化得到的动态参数转换为对应类型即可。
VB.NET 实现
' 原有JSON解析逻辑保留 Dim inputJson As String = "['Sample Input',2]" Dim lstObjects As List(Of Object) = JsonConvert.DeserializeObject(Of List(Of Object))(inputJson) Dim method As MethodInfo = consoleObject.GetType().GetMethod("ReflectionMethod") ' 按目标方法参数类型自动对齐入参类型 Dim methodParams = method.GetParameters() Dim invokeParams(lstObjects.Count - 1) As Object For i As Integer = 0 To methodParams.Length - 1 Dim targetParamType = methodParams(i).ParameterType Dim rawValue = lstObjects(i) If targetParamType.IsEnum Then ' 处理枚举类型转换 invokeParams(i) = Enum.ToObject(targetParamType, rawValue) Else ' 处理常规类型转换(兼容Int64转Int32、字符串转基础值类型等场景) invokeParams(i) = Convert.ChangeType(rawValue, targetParamType) End If Next ' 传入类型对齐后的参数执行调用 method.Invoke(consoleObject, invokeParams)
C# 实现
// 原有JSON解析逻辑保留 string inputJson = "['Sample Input',2]"; List<object> lstObjects = JsonConvert.DeserializeObject<List<object>>(inputJson); MethodInfo method = consoleObject.GetType().GetMethod("ReflectionMethod"); // 按目标方法参数类型自动对齐入参类型 ParameterInfo[] methodParams = method.GetParameters(); object[] invokeParams = new object[lstObjects.Count]; for (int i = 0; i < methodParams.Length; i++) { Type targetParamType = methodParams[i].ParameterType; object rawValue = lstObjects[i]; if (targetParamType.IsEnum) { // 处理枚举类型转换 invokeParams[i] = Enum.ToObject(targetParamType, rawValue); } else { // 处理常规类型转换(兼容Int64转Int32、字符串转基础值类型等场景) invokeParams[i] = Convert.ChangeType(rawValue, targetParamType); } } // 传入类型对齐后的参数执行调用 method.Invoke(consoleObject, invokeParams);
扩展适配说明
- 如果业务中枚举值在JSON里以字符串形式存储(例如用
"Tuesday"代替数字2),只需在枚举处理分支增加判断,当原始值为字符串类型时调用Enum.Parse完成转换即可,逻辑依然通用 - 如果方法定义了可空类型参数(例如
Days?),只需先通过Nullable.GetUnderlyingType取出可空类型的实际基础类型,再走上述转换逻辑即可 - 上述逻辑兼容所有常规值类型、引用类型的参数场景,不需要针对单个方法做单独适配,适合批量处理不同签名的反射调用需求。
内容的提问来源于stack exchange,提问作者sujith karivelil
相关产品推荐
相关产品推荐

