Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Here is a simplified version of Per Hejndorf's CSV idea (without the memory overhead as it yields each line in turn). Due to popular demand it also supports both fields and simple properties by use of <code>Concat</code>.</p> <h2>Update 18 May 2017</h2> <p>This example was never intended to be a complete solution, just advancing the original idea posted by Per Hejndorf. To generate valid CSV you need to replace any text delimiter characters, within the text, with a sequence of 2 delimiter characters. e.g. a simple <code>.Replace("\"", "\"\"")</code>.</p> <h2>Update 12 Feb 2016</h2> <p>After using my own code again in a project today, I realised I should not have taken anything for granted when I started from the example of <code>@Per Hejndorf</code>. It makes more sense to assume a default delimiter of "," (comma) and make the delimiter the second, <em>optional</em>, parameter. My own library version also provides a 3rd <code>header</code> parameter that controls whether a header row should be returned as sometimes you only want the data.</p> <h2>e.g.</h2> <pre><code>public static IEnumerable&lt;string&gt; ToCsv&lt;T&gt;(IEnumerable&lt;T&gt; objectlist, string separator = ",", bool header = true) { FieldInfo[] fields = typeof(T).GetFields(); PropertyInfo[] properties = typeof(T).GetProperties(); if (header) { yield return String.Join(separator, fields.Select(f =&gt; f.Name).Concat(properties.Select(p=&gt;p.Name)).ToArray()); } foreach (var o in objectlist) { yield return string.Join(separator, fields.Select(f=&gt;(f.GetValue(o) ?? "").ToString()) .Concat(properties.Select(p=&gt;(p.GetValue(o,null) ?? "").ToString())).ToArray()); } } </code></pre> <p><strong>so you then use it like this for comma delimited:</strong></p> <pre><code>foreach (var line in ToCsv(objects)) { Console.WriteLine(line); } </code></pre> <p><strong>or like this for another delimiter (e.g. TAB):</strong></p> <pre><code>foreach (var line in ToCsv(objects, "\t")) { Console.WriteLine(line); } </code></pre> <h2>Practical examples</h2> <p><strong>write list to a comma-delimited CSV file</strong></p> <pre><code>using (TextWriter tw = File.CreateText("C:\testoutput.csv")) { foreach (var line in ToCsv(objects)) { tw.WriteLine(line); } } </code></pre> <p><strong>or write it tab-delimited</strong></p> <pre><code>using (TextWriter tw = File.CreateText("C:\testoutput.txt")) { foreach (var line in ToCsv(objects, "\t")) { tw.WriteLine(line); } } </code></pre> <p><em>If you have complex fields/properties you will need to filter them out of the select clauses.</em></p> <hr> <h2>Previous versions and details below:</h2> <p>Here is a simplified version of Per Hejndorf's CSV idea (without the memory overhead as it yields each line in turn) <strong>and has only 4 lines of code :)</strong></p> <pre><code>public static IEnumerable&lt;string&gt; ToCsv&lt;T&gt;(string separator, IEnumerable&lt;T&gt; objectlist) { FieldInfo[] fields = typeof(T).GetFields(); yield return String.Join(separator, fields.Select(f =&gt; f.Name).ToArray()); foreach (var o in objectlist) { yield return string.Join(separator, fields.Select(f=&gt;(f.GetValue(o) ?? "").ToString()).ToArray()); } } </code></pre> <p><strong>You can iterate it like this:</strong></p> <pre><code>foreach (var line in ToCsv(",", objects)) { Console.WriteLine(line); } </code></pre> <p>where <code>objects</code> is a strongly typed list of objects.</p> <h2>This variation includes both public fields and simple public properties:</h2> <pre><code>public static IEnumerable&lt;string&gt; ToCsv&lt;T&gt;(string separator, IEnumerable&lt;T&gt; objectlist) { FieldInfo[] fields = typeof(T).GetFields(); PropertyInfo[] properties = typeof(T).GetProperties(); yield return String.Join(separator, fields.Select(f =&gt; f.Name).Concat(properties.Select(p=&gt;p.Name)).ToArray()); foreach (var o in objectlist) { yield return string.Join(separator, fields.Select(f=&gt;(f.GetValue(o) ?? "").ToString()) .Concat(properties.Select(p=&gt;(p.GetValue(o,null) ?? "").ToString())).ToArray()); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload