我在使用反射转储一些对象属性的例程上得到此错误,类似于下面的代码.
MemberInfo[] members = obj.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance) ;
foreach (MemberInfo m in members)
{
PropertyInfo p = m as PropertyInfo;
if (p != null)
{
object po = p.GetValue(obj, null);
...
}
}
Run Code Online (Sandbox Code Playgroud)
实际错误是"调用目标抛出了异常",内部异常为"只能在Type.IsGenericParameter为true的Type上调用Method".
在调试器obj的这个阶段出现
{Name = "SqlConnection" FullName = "System.Data.SqlClient.SqlConnection"}
Run Code Online (Sandbox Code Playgroud)
使用System.RuntimeType类型
方法m是{System.Reflection.MethodBase DeclaringMethod}
请注意,obj的类型为System.RuntimeType,成员包含188个项目,而简单的typeof(System.Data.SqlClient.SqlConnection).GetMembers(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)仅返回65.
我尝试在obj和p.PropertyType上检查isGenericParameter,但对于大多数属性(包括p.GetValue工作的那些属性),这似乎都是错误的.
那么究竟什么是"Type.IsGenericParameter为真的类型",更重要的是如何在没有try/catch的情况下避免这个错误?
Mar*_*ell 15
那究竟什么是"Type.IsGenericParameter为真的类型"
这意味着它是开放泛型类型中的泛型类型参数 - 即我们尚未选择的类型T; 例如:
// true
bool isGenParam = typeof(List<>).GetGenericArguments()[0].IsGenericParameter;
// false (T is System.Int32)
bool isGenParam = typeof(List<int>).GetGenericArguments()[0].IsGenericParameter;
Run Code Online (Sandbox Code Playgroud)
所以; 你有一些开放的仿制药吗?也许你可以举一个例子说明你从哪里来的obj?
Eri*_*ith 13
首先,你已经做出了错误的假设,也就是说,你已经假定它members已经返回了一个实例的成员System.Data.SqlClient.SqlConnection,而它没有.返回的是一个实例的成员System.Type.
从DeclaringType的MSDN文档:
DeclaringMethod在IsGenericParameter属性为false 的类型上 获取属性会引发属性InvalidOperationException.
所以...... InvalidOperationException抛出一个是可以理解的,因为很自然,你不会在这里处理一个开放的泛型类型.有关开放泛型类型的解释,请参阅Marc Gravells答案.