.NET反射 - 将数组类型的属性值转换为逗号分隔的字符串

时间:2013-04-02 06:18:25

标签: .net arrays reflection

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

我遇到了麻烦 - 如果属性是数组类型会怎么样?我确实获得了该属性的PropertyInfo结构,我可以看到该属性是一个数组,我甚至可以得到该数组属性的值:

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

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

我尝试过像

这样的事情
string.Join(", ", value);

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

有没有聪明的方法将这个“数组的东西”转换为逗号分隔的字符串而没有很多if(...)else { .... }子句?

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

2 个答案:

答案 0 :(得分:6)

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

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

尽管由于array covariance in 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>());
    }
}

答案 1 :(得分:2)

这是最简单的解决方案,适用于所有类型的集合,包括数组(IEnumerable是我们可以提出的最不常见的基础):

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