【问题标题】:Check if Property is List using Reflection in C#在 C# 中使用反射检查属性是否为列表
【发布时间】:2016-07-27 15:56:00
【问题描述】:

我现在被困在展示我的对象的价值。其中一些确实有List<string>properties,使用ToString()Method 会导致麻烦。这是我在基类中使用的代码,用于将属性的名称和值转换为字符串。

public override string ToString()
    {
        string content = "";
        foreach (var prop in this.GetType().GetProperties())
        {
            if (prop.PropertyType is IList<string> && prop.GetType().IsGenericType && prop.GetType().GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>)))
                content += prop.Name + " = " + PrintList((List<string>)prop.GetValue(this));
            else
            content += prop.Name + " = " + prop.GetValue(this) + "\r\n";
        }
        content += "\r\n";
        return content;
    }

    private string PrintList(List<string> list)
    {
        string content = "[";
        int i = 0;
        foreach (string element in list)
        {
            content += element;
            if (i == list.Count)
                content += "]";
            else
                content += ", ";
        }
        return content;
    }

无论如何,检查属性是否为列表不起作用。这可能是一个愚蠢的问题,或者是一种不好的反思方式,但我对它有点陌生,如果能帮助我弄清楚发生了什么,我将不胜感激。

【问题讨论】:

  • try 是 IEnumerable
  • prop.PropertyType.IsAssignableFrom(typeof(IList&lt;string&gt;))

标签: c# list reflection tostring


【解决方案1】:
public override string ToString()
{
    StringBuilder content = new StringBuilder();
    foreach (var prop in this.GetType().GetProperties())
    {
        var propertyType = prop.PropertyType;
        var propertyValue = prop.GetValue(this);
        if (propertyValue != null)
        {
            if (propertyValue is IEnumerable<string>)
                content.AppendFormat("{0} = {1}", prop.Name, PrintList(propertyValue as IEnumerable<string>));
            else
                content.AppendFormat("{0} = {1}", prop.Name, propertyValue.ToString());
        }
        else
            content.AppendFormat("{0} = null", prop.Name);
        content.AppendLine();
    }

    return content.ToString();
}

private string PrintList(IEnumerable<string> list)
{
    var content = string.Join(",", list.Select(i => string.Format("[{0}]", i)));
    return content;
}

【讨论】:

  • 完美运行!谢谢。
【解决方案2】:

我会这样做;

var property = prop.GetValue(this);

// try to cast as IEnumerable<string> -- will set to null if it's not.
var propertyStrings = property as IEnumerable<string>;
if (propertyStrings != null) {
    foreach(var s in propertyStrings) {
        // do something here with your strings.    
    }   
}

此外,不要使用+ 运算符连接字符串,而是查看StringBuilder,这对内存和速度都有好处。

【讨论】:

  • 我看到在strings 上使用+= 效率低下,但为什么+ 会不好?
  • @Downvoter 与 += 相同。要做到a = b + c,需要在内存中分配字符串b + c,然后赋值给a。比如说,添加 1M 个字符串需要 1M 个字符串分配,每次你这样做时,分配的开销会越来越大,因为结果会越来越大。如果您所有的字符串都是s 字符长,则添加为 O(s + 2s + 3s + 4s + 5s +6s ... 1000000s)。我认为这是 O(s.n^2)。 StringBuilder 预先分配内存,当它用完时数组加倍,所以添加一个字符串是 O(s),所有字符串都是 O(s.n)。
  • 感谢StringBuilder 的提示! @史蒂夫库珀
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-31
  • 1970-01-01
  • 1970-01-01
  • 2017-11-04
  • 2018-01-11
  • 1970-01-01
  • 2014-03-06
相关资源
最近更新 更多