7

我正在使用反射检查 .NET 对象以将它们转储到日志中。

我遇到了一个障碍——如果属性是数组类型怎么办?我确实得到了PropertyInfo该属性的结构,我可以看到该属性是一个数组,我什至可以得到该数组属性的值:

if(propertyInfo.PropertyType.IsArray)
{
    var value = propertyInfo.GetValue(myObject, null);
}

但现在我被困住了。当我查看 Visual Studio 调试器时,它显示为int[3]- 所以 VS 知道它是一个由三个整数组成的数组 - 但是我现在如何将其转换为代表这三个整数的逗号分隔字符串?

我尝试过类似的事情

string.Join(", ", value);

和其他人 - 但我一直在努力解决value“动态”的事实,例如它可能是 aint[]或 adecimal[]甚至是其他东西 - 所以我不能静态输入它......如果我不输入它,那么返回奇怪的string.Join()结果(绝对不是我要找的......)

有没有什么聪明的方法可以将这个“一些东西的数组”转换为一个逗号分隔的字符串,而不需要很多if(...)andelse { .... }子句?

不知何故,我现在正处于大脑冻结状态 - 任何解冻这种冻结的想法都将受到欢迎!

4

2 回答 2

8

好吧,似乎解决此问题的最简单方法是将其转换为IEnumerable<object>. 像这样:

if(propertyInfo.PropertyType.IsArray)
{
    var values = (IEnumerable)propertyInfo.GetValue(myObject, null);
    var stringValue = string.Join(", ", values.OfType<object>());
}

虽然,由于c# 中的数组协变,如果values引用类型的数组,它应该可以转换为object[]. 对于这种情况,您可以改用它:

if(propertyInfo.PropertyType.IsArray)
{
    var values = (IEnumerable)propertyInfo.GetValue(myObject, null);
    var elementType = propertyInfo.PropertyType.GetElementType();
    if (elementType != null && !elementType.IsValueType)
    {
        var stringValue = string.Join(", ", (object[])values);
    }
    else
    {
        var stringValue = string.Join(", ", values.OfType<object>());
    }
}
于 2013-04-02T06:27:57.903 回答
2

这是适用于包括数组在内的所有类型的集合的最简单的解决方案(这IEnumerable是我们能想到的最不常见的基础):

string.Join(", ", ((IEnumerable)value).Cast<object>().Select(i => i.ToString()));

于 2013-04-02T06:28:18.650 回答