2017-04-10 102 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爲空

相關問題