尝试遍历 CsvHelper 中的记录会引发 ConfigurationException 错误
Trying to iterate over records from CsvHelper throws ConfigurationException error
我正在尝试遍历 .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() 方法,但无济于事。
编辑 1:
在尝试创建自定义 class 之后,我 运行 进入了另一个错误,这次是在我什至 运行 代码之前来自编译器。
本质上,在这段代码中:
foreach (string item in ans)
{
Debug.Log(item);
}
foreach 被高亮显示并显示一条错误 "Cannot convert type 'instructions.ScriptsList' to 'string'"。我的文件名为 "instructions.cs".
还有一些可能是问题所在的额外信息:
1) 我正在 IEnumerator 中编写这段代码,但我不认为这应该是一个问题,因为我在其中还有其他 "foreach" 行。除非 CsvHelper 使用某些在 IEnumerator 中不起作用的代码?
2) 我的 .csv 文件是在 excel 中创建的,它们确实有 headers。它实际上只是 "Yes" 和 "No" 的多个列。在 Excel 中创建它并将其保存为 .csv(逗号分隔)是否会影响 CsvHelper 读取它的方式?
3) class 写在这个函数上面有关系吗? (我知道这是基本的,但我是 C# 的新手,我注意到在很多文档中 class 通常写在函数下面)
非常感谢您的帮助!
您收到的错误消息是指它无法使用给定的配置进行填充。
您想给 GetRecords<>
一个 class 或结构,它将用 .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
文件缺少 header 行(即第一行指定每列代表的内容),您可以将 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
, or simply 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);
}
对于您更新的问题:
- 这是我的错字。忘记将
foreach
项目变量从 string
更改为 ScriptsList
。我已经更新了我的答案。您的代码段应该是:
foreach (ScriptsPath item in ans)
{
Debug.Log(item);
}
没有。没有区别。唯一需要注意的是,有时 .csv
的格式为分号 ;
而不是逗号 ,
作为分隔符。但是 .csv
是最基本的格式之一
没有。如果 class
、struct
和 enum
占用相同的 file/example,则通常将其写在文件底部和 class 下方。它是 C# 语法的一部分,C# 编译器 不 需要类型定义的特定位置。这与您在 top-to-bottom 方法中编写的代码不同,而类型定义遵循更广泛的 tree-like 结构。
您用 C# 编写的代码流只是 C# 完整语法的一部分。在我看来,C# 的强大之处在于它的其余语法,例如名称空间、属性、枚举器方法、可访问性修饰符等。
我正在尝试遍历 .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() 方法,但无济于事。
编辑 1:
在尝试创建自定义 class 之后,我 运行 进入了另一个错误,这次是在我什至 运行 代码之前来自编译器。
本质上,在这段代码中:
foreach (string item in ans)
{
Debug.Log(item);
}
foreach 被高亮显示并显示一条错误 "Cannot convert type 'instructions.ScriptsList' to 'string'"。我的文件名为 "instructions.cs".
还有一些可能是问题所在的额外信息:
1) 我正在 IEnumerator 中编写这段代码,但我不认为这应该是一个问题,因为我在其中还有其他 "foreach" 行。除非 CsvHelper 使用某些在 IEnumerator 中不起作用的代码?
2) 我的 .csv 文件是在 excel 中创建的,它们确实有 headers。它实际上只是 "Yes" 和 "No" 的多个列。在 Excel 中创建它并将其保存为 .csv(逗号分隔)是否会影响 CsvHelper 读取它的方式?
3) class 写在这个函数上面有关系吗? (我知道这是基本的,但我是 C# 的新手,我注意到在很多文档中 class 通常写在函数下面)
非常感谢您的帮助!
您收到的错误消息是指它无法使用给定的配置进行填充。
您想给 GetRecords<>
一个 class 或结构,它将用 .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
文件缺少 header 行(即第一行指定每列代表的内容),您可以将 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
, or simply 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);
}
对于您更新的问题:
- 这是我的错字。忘记将
foreach
项目变量从string
更改为ScriptsList
。我已经更新了我的答案。您的代码段应该是:
foreach (ScriptsPath item in ans)
{
Debug.Log(item);
}
没有。没有区别。唯一需要注意的是,有时
.csv
的格式为分号;
而不是逗号,
作为分隔符。但是.csv
是最基本的格式之一没有。如果
class
、struct
和enum
占用相同的 file/example,则通常将其写在文件底部和 class 下方。它是 C# 语法的一部分,C# 编译器 不 需要类型定义的特定位置。这与您在 top-to-bottom 方法中编写的代码不同,而类型定义遵循更广泛的 tree-like 结构。您用 C# 编写的代码流只是 C# 完整语法的一部分。在我看来,C# 的强大之处在于它的其余语法,例如名称空间、属性、枚举器方法、可访问性修饰符等。