Skip to main content

From list to delimited string

I just read a blog post from Johan Olofsson where he describes how he uses a extension method to create a string representation of any list. I found it very interesting since I've written something very similar. I wanted to share my own version here, last modified 2008-06-28, almost a year from now, if we should trust the date stamp.

public static class EnumerableExtensions
{
    public static string ToDelimitedString<T>(this IEnumerable<T> list, string separator)
    {
        return ToDelimitedString(list, separator, DefaultConverter);
    }

public static string ToDelimitedString&lt;T&gt;(this IEnumerable&lt;T&gt; list, string separator, Converter&lt;T, string&gt; converter)
{
    // List can&#39;t be null  
    if (list == null)
    {
        throw new ArgumentNullException(&quot;list&quot;, &quot;Tried to create a string from a list that was null&quot;);
    }

    if (separator == null)
    {
        throw new ArgumentNullException(&quot;separator&quot;, &quot;Must specify a separator even if it is string.Empty&quot;);
    }
    Contract.EndContractBlock();

    // If converter was null, we probably wanted default converter  
    if (converter == null)
    {
        return list.ToDelimitedString(separator, DefaultConverter);
    }

    // Start the process of creating the string  
    var sb = new StringBuilder();
    foreach (var o in list)
    {
        sb.Append(converter(o));
        sb.Append(separator);
    }

    /* Remove last seperator (if there is one) */
    if (sb.Length &gt; 0)
    {
        sb.Length -= separator.Length;
    }

    return sb.ToString();
}

private static string DefaultConverter&lt;T&gt;(T item)
{
    return item.ToString();
}

}

The main difference between mine and Johans solution is that I've chosen to remove the last delimiter after the foreach and Johan does it in the for loop. It really does not matter for small n and I don't believe that this would be a good aproach for big n, anyway. (thinking Parallel Fx) This is how you use my extension methods.

public static void Main(string[] args)
{
    // Simple example
    string[] names = { "Joe", "Jack", "James" };
    names.ToDelimitedString(",");

// A bit more complex
var books = new Book[]
                {
                    new Book { Isbn = 1590598504, Title = &quot;Expert F#&quot;, Price = 614},
                    new Book { Isbn = 735619670, Title = &quot;Code Complete&quot;, Price = 324},
                };
books.ToDelimitedString(&quot;\n&quot;, book =&gt; string.Format(&quot;ISBN={0}, Title={1}, Price={2:c}&quot;, book.Isbn, book.Title, book.Price));

}

Why can't you just override ToString() on the Book class? While that would be an alternative, it requires me to supply a format that would be able to recreate the instance through a Parse method. (ref. Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries) This time I might just want to output the contents of this book-array to the screen. And sometimes you're just not the owner of that class you'd like to output. Happy coding!

comments powered by Disqus