为什么从IEnumerable类型的out参数返回List不返回列表中的项?

时间:2017-04-10 08:02:22

标签: c# out

我发现了一个我无法解释的特殊问题。我找到了初始问题的解决方法,但想知道为什么以及如何发生以下情况。因为即使在查看文档后我也无法解释这种行为。

初始问题

我有一个解析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<>类型时枚举它会产生零结果}?

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

2 个答案:

答案 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