I'm trying to create a generic method that will take in a List<T>
and a List<Tuple<string,string, int>>
so that I can write out to a CSV. I want the method to be able to take in any single level List<object>
passed to it and using the Tuple list which will contain the correct column names and the order in which the columns should appear, however, I've never worked with a Tuple in this manner and so I'm not certain how to make the order part work with the Tuple.
So far I have this:
protected List<Tuple<string, string, int>> CreateColumnOrder()
{
var columns = new List<Tuple<string, strint, int>>();
columns.Add(Tuple.Create("OriginalColumnName", "New Column Name", 0);
columns.Add(Tuple.Create("OriginalColumnName", "New Column Name", 2);
columns.Add(Tuple.Create("OriginalColumnName", "New Column Name", 1);
return columns;
}
public FileInfo GenericCsvFile<T>(List<T> list, List<Tuple<string, string, int>> columns)
{
if(list != null)
{
//File logic here...
StringBuilder sb = new StringBuilder();
bool IsFirstRow = true;
int rowCounter = 1;
//Re-order the columns here before they get written out...
foreach (T item in list)
{
PropertyInfo[] propInfo = item.GetType().GetProperties();
while (isFirstRow)
{
sb.Append(WriteColumnName(columns));
isFirstRow = false;
}
foreach (PropertyInfo info in propInfo)
{
object value = info.GetValue(item, null);
sb.Append("\"").Append(value).Replace("\"", "''").Append("\"");
rowCounter++;
if (rowCounter == list.Count)
{
sb.Append(Environment.NewLine);
using (var sw = file.AppendText())
{
sw.Write(sb.ToString());
sw.Close();
sw.Dispose();
}
}
else
sb.Append(Delimiter);
}
}
}
return file;
}
}
protected StringBuilder WriteColumnName(List<Tuple<string, string, int>> columns)
{
StringBuilder sb = new StringBuilder();
//Same here, how to use the Tuple order to write the column names...
foreach(var c in columns)
sb.Append("\"").Append(c.Item2).Replace("\"", "''").Append("\"");
return sb;
}
UPDATED: I'm posting the solution to my particular problem, special credit goes to @cloud120 for helping me with sorting the Tuple.
public FileInfo GenericCsvFile<T>(List<T> list, List<Tuple<string, string, int>> columns)
{
if(list != null)
{
//File logic here...
StringBuilder sb = new StringBuilder();
bool IsFirstRow = true;
int rowCounter = 0;
if(columns != null)
columns.Sort((a,b) => a.Item3.CompareTo(b.Item3));
//moved this here to avoid reflection every time the loop was processed
PropertyInfo[] propInfo = item.GetType().GetProperties();
int count = propInfo.Length;
foreach (T item in list)
{
if(isFirstRow)
{
sb.Append(WriteColumnName(columns));
sb.Append(Environment.NewLine);
isFirstRow = false;
}
int infoCount = 0;
foreach (var column in columns)
{
var value = item.GetType().GetProperty(column.Item1).GetValue(item,null);
sb.Append(value);
infoCount++;
rowCounter++;
if (rowCounter == list.Count)
{
sb.Append(Environment.NewLine);
using (var sw = file.AppendText())
{
sw.Write(sb.ToString());
sw.Close();
sw.Dispose();
}
}
else
sb.Append(infoCount == count ? Environment.NewLine : ",";
}
}
}
return file;
}
}
protected StringBuilder WriteColumnName(List<Tuple<string, string, int>> columns)
{
StringBuilder sb = new StringBuilder();
foreach(var c in columns)
sb.Append(c.Item2).Append(",");
return sb;
}