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) 帮助解决了我的问题。

感谢帮助