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);
使用PropertyInfo
的GetIndexParameters()
方法判断属性是否被索引,如果是,要么跳过,要么回到绘图板看看如何您可以生成它需要的索引,以便 return 一个有意义的值而不会失败。
如果您想要引用 IEnumerable 而不仅仅是它的项目,您可以使用以下方法获取它:
if (propertyInfo.GetMethod.IsPublic)
{
var value = propertyInfo.GetMethod.Invoke(Instance, null);
}
我有以下问题:
我目前正在编写与 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);
使用PropertyInfo
的GetIndexParameters()
方法判断属性是否被索引,如果是,要么跳过,要么回到绘图板看看如何您可以生成它需要的索引,以便 return 一个有意义的值而不会失败。
如果您想要引用 IEnumerable 而不仅仅是它的项目,您可以使用以下方法获取它:
if (propertyInfo.GetMethod.IsPublic)
{
var value = propertyInfo.GetMethod.Invoke(Instance, null);
}