C# 反射从 ICollection 获取值
C# Reflection get value from ICollection
我正在为一个问题而苦苦挣扎,但找不到解决方案。
在我的代码的某个时刻,抛出一个SqlException
。
我创建了一个方法,使用反射来遍历来自任何异常的所有属性并执行一些逻辑,但我遇到了这个问题。
其成员之一调用 Errors
,继承自 SqlErrorCollection
。 (根据 MSDN 文档,class 定义为
[SerializableAttribute]
[ListBindableAttribute(false)]
public sealed class SqlErrorCollection : ICollection,
我用来检查 属性 是否为列表的代码不适用于此 属性:
if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType)
&& typeof(ICollection).IsAssignableFrom(prop.PropertyType)
&& prop.PropertyType.IsGenericType)
当我使用下面的代码获得它的价值时
property.GetValue(myObject, null);
引发了 TargetParameterCountException(参数计数不匹配)。
有人知道为什么吗?
遍历 SqlException
中的错误非常容易。如果这就是你想要的,给你。
private string GenerateMessage(SqlException ex)
{
StringBuilder builder = new StringBuilder();
foreach (SqlError error in ex.Errors)
{
builder.Append(error.ToString());
}
return builder.ToString();
}
prop.PropertyType.IsGenericType
检查将 return 错误,因为 SqlErrorsCollection 是非泛型的。至于问题的第二部分——我无法在获取 属性 值时重现此异常。以下代码无异常执行:
// create inner sql error collection instance through reflection
var sqlErrorCollCtor = typeof(SqlErrorCollection).GetConstructors(
BindingFlags.Instance
| BindingFlags.NonPublic
| BindingFlags.NonPublic).FirstOrDefault();
var errorCollection = (SqlErrorCollection)sqlErrorCollCtor.Invoke(null);
// create sql exception instance through reflection
var sqlExceptionCtor = typeof(SqlException).GetConstructors(
BindingFlags.Instance
| BindingFlags.NonPublic
| BindingFlags.NonPublic).FirstOrDefault();
var exception = sqlExceptionCtor.Invoke(
new object[] { "Test", errorCollection, null, new Guid() });
// retrieve Errors property
var prop = exception.GetType().GetProperty("Errors");
if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType)
&& typeof(ICollection).IsAssignableFrom(prop.PropertyType) )
// && prop.PropertyType.IsGenericType)
{
var val = prop.GetValue(exception, null);
Console.WriteLine(val);
}
会不会是您正在从另一个对象而不是 SqlException 中检索值?
由于 pmcoltrane 提供的见解,错误 属性 是一个索引 属性。文章 iterating through an indexed property (Reflection) 帮助解决了我的问题。
感谢帮助
我正在为一个问题而苦苦挣扎,但找不到解决方案。
在我的代码的某个时刻,抛出一个SqlException
。
我创建了一个方法,使用反射来遍历来自任何异常的所有属性并执行一些逻辑,但我遇到了这个问题。
其成员之一调用 Errors
,继承自 SqlErrorCollection
。 (根据 MSDN 文档,class 定义为
[SerializableAttribute]
[ListBindableAttribute(false)]
public sealed class SqlErrorCollection : ICollection,
我用来检查 属性 是否为列表的代码不适用于此 属性:
if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType)
&& typeof(ICollection).IsAssignableFrom(prop.PropertyType)
&& prop.PropertyType.IsGenericType)
当我使用下面的代码获得它的价值时
property.GetValue(myObject, null);
引发了 TargetParameterCountException(参数计数不匹配)。
有人知道为什么吗?
遍历 SqlException
中的错误非常容易。如果这就是你想要的,给你。
private string GenerateMessage(SqlException ex)
{
StringBuilder builder = new StringBuilder();
foreach (SqlError error in ex.Errors)
{
builder.Append(error.ToString());
}
return builder.ToString();
}
prop.PropertyType.IsGenericType
检查将 return 错误,因为 SqlErrorsCollection 是非泛型的。至于问题的第二部分——我无法在获取 属性 值时重现此异常。以下代码无异常执行:
// create inner sql error collection instance through reflection
var sqlErrorCollCtor = typeof(SqlErrorCollection).GetConstructors(
BindingFlags.Instance
| BindingFlags.NonPublic
| BindingFlags.NonPublic).FirstOrDefault();
var errorCollection = (SqlErrorCollection)sqlErrorCollCtor.Invoke(null);
// create sql exception instance through reflection
var sqlExceptionCtor = typeof(SqlException).GetConstructors(
BindingFlags.Instance
| BindingFlags.NonPublic
| BindingFlags.NonPublic).FirstOrDefault();
var exception = sqlExceptionCtor.Invoke(
new object[] { "Test", errorCollection, null, new Guid() });
// retrieve Errors property
var prop = exception.GetType().GetProperty("Errors");
if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType)
&& typeof(ICollection).IsAssignableFrom(prop.PropertyType) )
// && prop.PropertyType.IsGenericType)
{
var val = prop.GetValue(exception, null);
Console.WriteLine(val);
}
会不会是您正在从另一个对象而不是 SqlException 中检索值?
由于 pmcoltrane 提供的见解,错误 属性 是一个索引 属性。文章 iterating through an indexed property (Reflection) 帮助解决了我的问题。
感谢帮助