我发现了一个我无法解释的特殊问题。我找到了初始问题的解决方法,但想知道为什么以及如何发生以下情况。因为即使在查看文档后我也无法解释这种行为。
初始问题
我有一个解析csv文件的函数,并通过out参数返回错误列表和/或解析记录,如下所示:
public IEnumerable<string> ParseCsv(string file, out IEnumerable<string> records)
{
records = new List<string>();
//... (actual parsing)
records.Add("foo");
records.Add("bar");
return Enumerable.Empty<string>(); //Returning errors
}
//And calling the method:
IEnumerable<string> records;
ParseCsv("somefile.csv", out records);
//records yields zero records
解决方法
在确保解析逻辑正常工作后,我开始进一步调查。我最初的想法是,out
变量的值立即设置,任何进一步的调用都不会修改初始状态集。
后来我发现了一种解决方法,将out
参数标记为IList<>
而不是IEnumerable<>
。这反驳了我最初的想法,因为列表保持不变,并且对此列表的引用似乎是通过参数传递的。
public IEnumerable<string> ParseCsv(string file, out IList<string> records)
{
records = new List<string>();
//... (actual parsing)
records.Add("foo");
records.Add("bar");
return Enumerable.Empty<string>(); //Returning errors
}
//Calling:
IList<string> records;
ParseCsv("somefile.csv", out records);
解释
现在我无法解释为什么会发生这种情况,因为引用似乎指向与最初设置相同的列表实例,为什么在out
参数不是IList<>
类型时枚举它会产生零结果}?
我至少会期待运行时异常而不是这种奇怪的行为。
答案 0 :(得分:2)
records
的声明类型是IEnumerable<string>
。因此,即使您已为该变量分配List<string>
,您也只能(直接)调用IEnumerable<string>
接口支持的方法。
在您创建和填充列表时,没有理由要使用特定变量:
public IEnumerable<string> ParseCsv(string file, out IEnumerable<string> records)
{
var results = new List<string>();
records = results;
//... (actual parsing)
results.Add("foo");
results.Add("bar");
return Enumerable.Empty<string>(); //Returning errors
}
答案 1 :(得分:0)
您可以尝试像这样转换
List<string> recordsList = records.ToList();
如果您的IEnumarable为空,请注意ArgumentNullException