Extension method for converting generic lists to CSV in C# [Updated]

Over a year ago I published a post which showed a c# extension method which can be use to convert a generic  list to CSV. Recently, I came across a problem in the code. It does not handle Nullable<T> properly. The following is an update to the code which fixes the Nullable<T> issues. I also added a cheap option which converts camel case headers to distinct words.

public static string ToCSV<T>(this IEnumerable<T> list, bool showheader = true, bool processHeaders = false)
 var type = typeof(T);
 var properties = type.GetProperties();

//Setup expression constants
 var param = Expression.Parameter(type, "val");
 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 properties
 let tostringcall = Expression.Call(typeof(Convert).GetMethod("ToString", new Type[] { typeof(object) }), Expression.Convert( Expression.Property(param, prop), typeof(object)))
 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)

//Convert an instance of the object to a single csv line
 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();

if (showheader)
 //Create header row
 var header = String.Join(",", properties.Select(p => processHeaders ? Regex.Replace(p.Name, "(\\B[A-Z])", " $1").Trim() : p.Name).ToArray());

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

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 )

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s