4

I'm stuck at putting out the values of my objects at the moment. Some of them do have List<string>properties which causes trouble by using the ToString()Method. Here is the code I use in my base class to get the name and the value of the properties into a string.

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;
    }

Anyhow, the check if the propertie is a List does not work. This might be a dumb question and or a bad way to work with reflection but I'm kinda new to it and will appreciate any help to figure out what is going on.

P. Edge
  • 105
  • 1
  • 7

2 Answers2

4
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;
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472
3

I'd do this;

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.    
    }   
}

Also, instead of concatenatings strings with the + operator, take a look at StringBuilder, which is better for memory and speed.

Steve Cooper
  • 20,542
  • 15
  • 71
  • 88
  • I see the inefficiency in using `+=` on `string`s, but why would `+` be bad? – cadaniluk Jul 27 '16 at 16:07
  • @Downvoter same as +=. To do a = b + c, you need to allocate the string `b + c` in memory, then assign to a. To add, say, 1M strings requires 1M string allocations, and every time you do, the allocation gets more and more expensive as the result gets bigger and bigger. If all your strings are `s` chars long, adding is O(s + 2s + 3s + 4s + 5s +6s... 1000000s). I think that's O(s.n^2). StringBuilder allocates memory up front, doubling the array when it runs out, so it's O(s) to add a string and O(s.n) for all strings. – Steve Cooper Jul 27 '16 at 16:21
  • Thank you for the `StringBuilder` hint! @SteveCooper – P. Edge Jul 27 '16 at 18:06