PropertyInfo.GetValue(object) 因 IEnumerable<T> 而失败 [C#, Reflection]

PropertyInfo.GetValue(object) fails with IEnumerable<T> [C#, Reflection]

我有以下问题:
我目前正在编写与 PHP 的 var_dump 方法等效的 c#。它与 'simple' 类 和结构(甚至数组)完美配合。
我唯一的问题是涉及到其他 IEnumerable<T>,例如 List<T> 等:

调试器正在抛出 TargetParameterCountException。我的代码如下所示:

Type t = obj.GetType(); // 'obj' is my variable, i want to 'dump'
string s = "";
PropertyInfo[] properties = t.GetProperties();

for (int i = 0; i < properties.Length; i++)
{
    PropertyInfo property = properties[i];

    object value = property.GetValue(obj); // <-- throws exception

    if (value is ICollection)
    {
        // Code for array parsing - is irrelevant for this problem
    }
    else
        s += "Element at " + i + ": " + value.GetType().FullName + " " + value.ToString() + "\n";
}

return s;

我知道,我可以用 PropertyInfo.GetIndexParameters() 以某种方式获取索引,但我不知道如何正确使用它。

编辑:我还想指出,我既不知道 IEnumerable 的大小,也不知道编译时的 Type T。

这与实现 IEnumerable 的类型无关。相反,它是关于具有索引器的类型。索引器被认为是属性,但它们是特殊属性,在获取其值时需要为其提供索引参数。如果你不这样做,它就会像你在这里看到的那样出错。

您可以使用 GetIndexParameters() 并检查返回数组的计数以确定 属性 是否为索引器。这将使您可以跳过 属性(这是我假设您想要在此处执行的操作),或者使用它来获取其值。

不确定这是否是您的问题,但根据 MSDN:

You call the GetValue(Object) overload to retrieve the value of a non-indexed property; if you try to retrieve the value of an indexed property, the method throws a TargetParameterCountException exception.

来自同一页上的示例:

     if (prop.GetIndexParameters().Length == 0)
        Console.WriteLine("   {0} ({1}): {2}", prop.Name,
                          prop.PropertyType.Name,
                          prop.GetValue(obj));
     else
        Console.WriteLine("   {0} ({1}): <Indexed>", prop.Name,
                          prop.PropertyType.Name);

使用PropertyInfoGetIndexParameters()方法判断属性是否被索引,如果是,要么跳过,要么回到绘图板看看如何您可以生成它需要的索引,以便 return 一个有意义的值而不会失败。

如果您想要引用 IEnumerable 而不仅仅是它的项目,您可以使用以下方法获取它:

if (propertyInfo.GetMethod.IsPublic)
{

    var value = propertyInfo.GetMethod.Invoke(Instance, null);
}