Last active
May 27, 2019 10:22
-
-
Save shadeglare/42175f3fa535ac36ff04 to your computer and use it in GitHub Desktop.
Simple csv serializer for c#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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