2017-04-10 103 views
0

我发现了一个我无法解释的奇怪问题。我已经找到了解决最初问题的方法,但想知道为什么以及如何发生下列情况。因为即使在查看文档后我也无法解释这种行为。为什么从IEnumerable类型的out参数返回List不会返回列表中的项目?

首次发行

我有它通过out参数解析一个CSV文件并返回错误和/或解析记录列表的功能如下:

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<>类型?

我会至少期望一个运行时异常,而不是这种奇怪的行为。

+5

请提供[mcve]。从您在这里介绍的片段中很难看到发生了什么。我不希望这段代码能够编译,因为'records'的类型是'IEnumerable ',并且没有'Add'方法。 –

+0

如果你想使用out参数,为什么你要返回一个IEnumerable?难道你不希望返回一个布尔值,以确保解析是成功的(也可以称之为TryParseCsv?) – Icepickle

+0

@Ippickle同意这样会更好,但目标是获取文件中的所有错误,而不仅仅是验证它。 – Waaghals

回答

2

宣告的类型recordsIEnumerable<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

“您只能(直接)调用IEnumerable接口支持的方法”是的,这确实是这种情况。我被外部包中的'IEnumerable '上的扩展方法'Add(...)'欺骗了。我发现这个尝试在我的项目之外创建一个工作示例。 – Waaghals

0

你可以尝试这样

List<string> recordsList = records.ToList(); 

关注转换出来为ArgumentNullException如果您的IEnumarable为空

相关问题