我正在尝试遍历.csv文件以在控制台上输出。我正在使用CsvHelper,并且遵循了T的指南,但是每当我尝试遍历从GetRecords()方法获得的IEnumerable时,就会出现ConfigurationException。
这是我正在使用的代码
using (var reader_ans = new StreamReader("scriptlists/prac_iden_ans.csv"))
using (var csv_ans = new CsvReader(reader_ans))
{
var ans = csv_ans.GetRecords<string>();
foreach (string item in ans)
{
Debug.Log(item);
}
}
这很奇怪,因为这正是文档和多个网站中的内容。
出现的错误是这样的:
ConfigurationException: Types that inherit IEnumerable cannot be auto mapped. Did you accidentally call GetRecord or WriteRecord which acts on a single record instead of calling GetRecords or WriteRecords which acts on a list of records?
我想知道是否缺少一些愚蠢的东西,因为我刚接触C#。我也在Unity3D中对此进行编码,所以这可能是问题的一部分吗?
我也尝试在第一行使用.ToList()方法,但无济于事。
Edit1:
尝试创建自定义类后,我遇到了另一个错误,这次是在编译器甚至无法运行代码之前发生的。
本质上,在这段代码中:
foreach (string item in ans)
{
Debug.Log(item);
}
foreach突出显示,并显示错误消息“无法将类型'instructions.ScriptsList'转换为'string'”。我的文件名为“ instructions.cs”。
一些额外的信息也可能是问题所在
1)我正在IEnumerator中编写这段代码,但是我认为那不应该是一个问题,因为我确实有其他“ foreach”行。除非CsvHelper使用某些在IEnumerator中无法使用的代码?
2)我的.csv文件是在excel中创建的,并且确实具有标头。实际上,它只是“是”和“否”的多个列。在Excel中创建并将其另存为.csv(逗号分隔)是否会影响CsvHelper对其的读取方式?
3)在该函数上方编写类是否重要? (我知道这是一种基本的方法,但是我对C#还是很陌生,我已经注意到,在许多文档中,该类通常写在该函数的下面)
非常感谢您的帮助!
答案 0 :(得分:1)
您收到的错误消息是指它无法使用给定的配置进行填充。
您想给GetRecords<>
一个类或结构,它将使用您的.csv
中每一行的值来填充。您的脚本可能由于尝试将行填充为string
类型而失败,因此失败。
示例解决方案,假设您的.csv
与此类似:
您的prac_iden_ans.csv
文件:
Path
C:/example/path/one
C:/example/path/two
您的.cs
C#脚本文件:
void YourFunction() {
using (var reader_ans = new StreamReader("scriptlists/prac_iden_ans.csv"))
using (var csv_ans = new CsvReader(reader_ans))
{
var ans = csv_ans.GetRecords<ScriptsList>();
foreach (ScriptsList item in ans)
{
Debug.Log(item.Path);
}
}
}
class ScriptsList {
public string Path { get; set; }
}
但是,如果您的.csv
文件缺少标题行(即,第一行指定了每一列所代表的内容),则可以将CsvReader
配置为不希望有标题行。但是,然后必须告诉CsvReader
以不同的方式将哪些列映射到哪些属性。一种方法是IndexAttribute
。示例:
您的prac_iden_ans.csv
文件:
C:/example/path/one
C:/example/path/two
您的.cs
C#脚本文件:
void YourFunction() {
using (var reader_ans = new StreamReader("scriptlists/prac_iden_ans.csv"))
using (var csv_ans = new CsvReader(reader_ans))
{
csv_ans.Configuration.HasHeaderRecord = false;
var ans = csv_ans.GetRecords<ScriptsList>();
foreach (ScriptsList item in ans)
{
Debug.Log(item.Path);
}
}
}
class ScriptsList {
[Index(0)]
public string Path { get; set; }
}
但是,如果您只是逐行读取文件中的每一行,我建议您仅使用StreamReader
,File.OpenRead
或简单地使用File.ReadAllLines
。示例:
您的prac_iden_ans.csv
文件:
C:/example/path/one
C:/example/path/two
您的.cs
C#脚本文件:
string[] ans = File.ReadAllLines("scriptlists/prac_iden_ans.csv");
foreach (string item in ans)
{
Debug.Log(item);
}
答案 1 :(得分:1)
对于您的更新问题:
foreach
项目变量从string
更改为ScriptsList
。我已经更新了答案。您的代码段应为:foreach (ScriptsPath item in ans)
{
Debug.Log(item);
}
否。没有区别。唯一需要注意的是,有时.csv
的格式为分号;
,而不是逗号,
作为分隔符。但是.csv
是目前最基本的格式之一
否。如果文件class
,struct
和enum
占用相同的文件/示例,则通常在文件的底部和类的下方写入bookList
,export default {
name: "BookList", // template name
apollo: {
bookList: {
query: getBooksQuery // query
}
}
}
和apollo: {
bookList: getBooksQuery
}
。它是C#语法的一部分,并且C#编译器不需要要求类型定义的特定位置。这与您使用自上而下的方法编写的代码不同,而类型定义遵循的是树状结构。
您使用C#编写的代码流只是C#完整语法的一部分。我认为C#的强大功能来自其语法的其余部分,包括名称空间,属性,枚举器方法,可访问性修饰符等。