Skip to content

Instantly share code, notes, and snippets.

@shadeglare
Last active May 27, 2019 10:22
Show Gist options
  • Save shadeglare/42175f3fa535ac36ff04 to your computer and use it in GitHub Desktop.
Save shadeglare/42175f3fa535ac36ff04 to your computer and use it in GitHub Desktop.
Simple csv serializer for c#
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Globalization;
using System.Collections.Generic;
namespace Shadeglare.Utils
{
public sealed class CsvConverter
{
private static class CsvValue
{
public static String FromDate(DateTime value)
{
return value.TimeOfDay.TotalSeconds == 0 ?
value.ToString("yyyy-MM-dd") : value.ToString("yyyy-MM-dd HH:mm:ss");
}
public static String FromNullableDate(DateTime? cell)
{
return cell.HasValue ? FromDate(cell.Value) : String.Empty;
}
public static String FromString(String value)
{
var comma = value.Contains(",");
var quote = value.Contains("\"");
return (comma || quote) ?
QuoteString(quote ? EscapeQuotes(value) : value) : value;
}
public static String From<T>(T obj)
{
return FromString(Convert.ToString(obj, CultureInfo.InvariantCulture));
}
private static String QuoteString(String value)
{
return '"' + value + '"';
}
private static String EscapeQuotes(String value)
{
return value.Replace("\"", "\"\"");
}
}
private class CsvSerializer<T>
{
private IEnumerable<Tuple<PropertyInfo, Func<Object, String>>> PropertyValueConverters { get; set; }
public CsvSerializer()
{
this.PropertyValueConverters = typeof(T).GetProperties().Select(x =>
{
if (x.PropertyType == typeof(DateTime))
return Tuple.Create(x, (Func<Object, String>)(o => CsvValue.FromDate((DateTime)o)));
else if (x.PropertyType == typeof(DateTime?))
return Tuple.Create(x, (Func<Object, String>)(o => CsvValue.FromNullableDate((DateTime?)o)));
else
return Tuple.Create(x, (Func<Object, String>)CsvValue.From);
}).ToList();
}
private IEnumerable<String> ExtractPropertyValues(T obj)
{
return this.PropertyValueConverters.Select(x =>x.Item2(x.Item1.GetValue(obj, null)));
}
private IEnumerable<String> ExtractHeaders()
{
return this.PropertyValueConverters.Select(x => x.Item1.Name);
}
private String ToCsvRow(IEnumerable<String> values)
{
return String.Join(",", values);
}
public String Serialize(IEnumerable<T> entries)
{
using (var stream = new StringWriter() { NewLine = "\n" })
{
stream.WriteLine(ToCsvRow(ExtractHeaders()));
foreach (var entry in entries)
stream.WriteLine(ToCsvRow(ExtractPropertyValues(entry)));
return stream.ToString();
}
}
}
public static String Serialize<T>(IEnumerable<T> values)
{
var serializer = new CsvSerializer<T>();
return serializer.Serialize(values);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment