Extension method for converting generic lists to CSV in C#


I created the following class so I could easily convert a generic list to a CSV string.  This may be handy when you want to quickly export a moderately sized result set to Microsoft Excel.

    public static class CsvConverter
    {
        public static string ToCSV<T>(this IEnumerable<T> list)
        {
            var type = typeof(T);
            var props = type.GetProperties();

            //Setup expression constants
            var param = Expression.Parameter(type, "x");
            var doublequote = Expression.Constant("\"");
            var doublequoteescape = Expression.Constant("\"\"");
            var comma = Expression.Constant(",");

            //Convert all properties to strings, escape and enclose in double quotes
            var propq = (from prop in props
                         let tostringcall = Expression.Call(Expression.Property(param, prop), prop.ReflectedType.GetMethod("ToString",new Type[0]))
                         let replacecall = Expression.Call(tostringcall, typeof(string).GetMethod("Replace", new Type[] { typeof(String), typeof(String) }), doublequote, doublequoteescape)
                         select Expression.Call(typeof(string).GetMethod("Concat", new Type[] { typeof(String), typeof(String), typeof(String) }), doublequote, replacecall, doublequote)
                         ).ToArray();

            var concatLine = propq[0];
            for (int i = 1; i < propq.Length; i++)
                concatLine = Expression.Call(typeof(string).GetMethod("Concat", new Type[] { typeof(String), typeof(String), typeof(String) }), concatLine, comma, propq[i]);

            var method = Expression.Lambda<Func<T, String>>(concatLine, param).Compile();

            var header = String.Join(",", props.Select(p => p.Name).ToArray());

            return header + Environment.NewLine + String.Join(Environment.NewLine, list.Select(method).ToArray());
        }
    }

Adding this as an extension method for IEnumerable may not be the best thing since the above will fail if T is an object with no properties. However, you probably wouldn’t be converting something like a List of string to CSV anyways. If you are then you can simply use the following code

var csv = string.join(",",list.ToArray());  

The following console application sample demonstrates how the new method can be used. I hope someone finds this useful.

   class Program
    {
        static void Main(string[] args)
        {
            var list = new List<person>();
            var limit = 100;

            for (int x = 0; x < limit; x++)
            {
                var fname = "Ron";
                var lname = "Obvious";

                list.Add(new person()
                {
                    Age = x,
                    FirstName = fname,
                    LastName = lname
                });

            }
         
            var csv = list.ToCSV();

            Console.Write(csv);
            Console.ReadLine();

        }
    }

    class person
    {
        public int Age { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
Advertisements

2 thoughts on “Extension method for converting generic lists to CSV in C#

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s