C# 使用新行中的每个对象值将对象列表转换为csv的最快方法

C# 使用新行中的每个对象值将对象列表转换为csv的最快方法,c#,csv,C#,Csv,我的课程如下: public class Test { public int Id {get;set;} public string Name { get; set; } public string CreatedDate {get;set;} public string DueDate { get; set; } public string ReferenceNo { get; set; } public string Paren

我的课程如下:

public class Test
{
    public int Id {get;set;}
    public string Name { get; set; }
    public string CreatedDate {get;set;}
    public string DueDate { get; set; } 
    public string ReferenceNo { get; set; }       
    public string Parent { get; set; }
}
我有一个测试对象列表

List<Test>testobjs=new List();
但这不会根据需要放置\n,即每个对象


除了字符串构建之外,还有什么最快的方法可以做到这一点吗?请帮助…

您最好的选择是使用现有的库。它为您省去了自己弄明白的麻烦,并且可能会处理转义特殊字符、添加标题行等问题。 您可以使用ServiceStack中的。但是,在这方面还有其他几个问题。 然后,创建CSV将像
string CSV=CsvSerializer.SerializeToCsv(testobjs)一样简单

使用servicestack.text

Install-Package ServiceStack.Text
然后使用字符串扩展方法
ToCsv(T)/fromsv()

示例:

更新:
Servicestack.Text
现在在曾经商业化的v4中也是免费的。无需再指定版本!连载快乐

因为问题中提到了速度,我的兴趣被激发在相对性能可能是什么,以及我能以多快的速度获得它上

我知道StringBuilder被排除在外,但它仍然感觉可能是最快的,StreamWriter当然具有写入MemoryStream或直接写入文件的优势,这使它具有多功能性

所以我做了一个快速测试

我列出了50万个和你一样的东西

然后,我使用CsvSerializer进行序列化,并使用两个手动精简版本,一个使用StreamWriter到MemoryStream,另一个使用StringBuilder

手工编写的代码是为了处理引号,但没有更复杂的代码。这段代码非常紧凑,我只能管理最少的中间字符串,没有连接。。。但不是生产,当然也没有风格和灵活性

但这三种方法的输出都是相同的

时间安排很有趣:

序列化50万个对象,每个方法运行五次,每次运行到最接近的整数毫秒:

StringBuilder     703     734     828     671     718   Avge=     730.8
MemoryStream      812     937     874     890     906   Avge=     883.8
CsvSerializer   1,734   1,469   1,719   1,593   1,578   Avge=   1,618.6
这是一款拥有大量RAM的高端i7

在其他条件相同的情况下,我总是使用图书馆

但是,如果2:1的性能差异变得至关重要,或者RAM或其他问题在更大的数据集上夸大了差异,或者如果数据以块的形式到达并直接发送到磁盘,我可能会受到诱惑

为了以防万一,代码的核心(对于StringBuilder版本)是

是我发现的最快最轻的,可以在GitHub上找到。允许您通过属性属性指定选项。

使用Cinchoo ETL

Install-Package ChoETL

示例显示了如何使用它

List<Test> list = new List<Test>();

list.Add(new Test { Id = 1, Name = "Tom" });
list.Add(new Test { Id = 2, Name = "Mark" });

using (var w = new ChoCSVWriter<Test>(Console.Out)
    .WithFirstLineHeader()
    )
{
    w.Write(list);
}
有关更多信息,请转到github


您可以使用FileHelpers库将对象列表转换为csv

考虑给定的对象,向其添加DelimitedRecord属性

[DelimitedRecord(",")]
public class Test
{
    public int Id {get;set;}
    public string Name { get; set; }
    public string CreatedDate {get;set;}
    public string DueDate { get; set; } 
    public string ReferenceNo { get; set; }       
    public string Parent { get; set; }
 }
填充列表后,(根据问题,它是testobjs)

var engine=new FileHelperEngine();
engine.HeaderText=engine.GetFileHeader();
字符串dirPath=Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)+“\\”+ConfigurationManager.AppSettings[“MyPath”];
如果(!Directory.Exists(dirPath))
{
CreateDirectory(dirPath);
}
//文件位置,.csv文件存放的位置。
字符串filePath=Path.Combine(dirPath,“MyTestFile”+“.csv”);
WriteFile(filePath,testobjs);
这正好帮你完成任务。我用它生成数据报告已经有一段时间了,直到我切换到python


PS:回答太晚了,但希望这对某人有所帮助。

您是否覆盖了默认的
ToString
?不,我没有尝试覆盖。您能给我一个例子说明覆盖如何帮助实现这一点吗?与您的标题相反,您不是在寻找最快的方式,而是寻找任何功能方式<代码>字符串。Join(“,”,…)
不是编写CSV的正确方法。看,这与我的标题没有冲突,我只是说这是我在这里搜索得到的解决方案,再次阅读我的评论。你为什么明确要求“最快的方式”?你不只是在寻找“任何可行的方法”吗?谢谢你,因为它处理了换行符:)那里的配额是多少?“JSON、JSV和CSV序列化程序中的20种不同类型*”这是什么意思?20种不同的类。但是如果您使用的是v3,那么就没有限制了。也谢谢您推荐了一个很好的库。非常感谢您的分析。
Install-Package ChoETL.NETStandard
List<Test> list = new List<Test>();

list.Add(new Test { Id = 1, Name = "Tom" });
list.Add(new Test { Id = 2, Name = "Mark" });

using (var w = new ChoCSVWriter<Test>(Console.Out)
    .WithFirstLineHeader()
    )
{
    w.Write(list);
}
Id,Name,CreatedDate,DueDate,ReferenceNo,Parent
1,Tom,,,,
2,Mark,,,,
[DelimitedRecord(",")]
public class Test
{
    public int Id {get;set;}
    public string Name { get; set; }
    public string CreatedDate {get;set;}
    public string DueDate { get; set; } 
    public string ReferenceNo { get; set; }       
    public string Parent { get; set; }
 }
var engine = new FileHelperEngine<Test>();
engine.HeaderText = engine.GetFileHeader();
string dirPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" + ConfigurationManager.AppSettings["MyPath"];
if (!Directory.Exists(dirPath))
{
   Directory.CreateDirectory(dirPath);
}

//File location, where the .csv goes and gets stored.
string filePath = Path.Combine(dirPath, "MyTestFile_" + ".csv");
engine.WriteFile(filePath, testobjs);