我正在尝试创建一个通用方法,该方法将接收列表<T>
和列表<Tuple<string,string, int>>
,以便我可以写出CSV。我希望该方法能够接收传递给它的任何单个级别的列表<object>
,并使用包含正确的列名称和列应该出现的顺序的元组列表,但是,我从来没有以这种方式与元组合作,所以我不确定如何使订单部分与元组一起工作。
到目前为止,我有这个:
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;
}
更新: 我正在为我的特定问题发布解决方案,特别归功于@ cloud120,帮助我对元组进行排序。
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;
}