LINQ Select 仅在查看 Enumerable 时抛出 IOException

LINQ Select only throws IOException when the Enumerable is looked at

我目前正在使用 LINQ 将文件列表加载到 XDocuments 中,如下所示:

 var fileNames = new List<string>(){ "C:\file.xml" };

 var xDocs = fileNames.Select(XDocument.Load);

 var xDocs2 = xDocs.ToList(); // Crashes here    

如果我故意 'lock' 使用不同进程的文件之一,只有当我真正开始查看我一直在生成的 XDocuments 时,即调用 ToList() 时,才会抛出 IOException。

谁能解释这是为什么,以及如何最好地处理这个错误?如果可能的话,我仍然希望能够访问工作中的 XDocuments。

这就是 linq .Select 是 IEnumerable 的原因,如果您将 IEnumerable 设为列表,则首先调用元素。然后你检查所有的元素。

Can anyone explain why this is

正如许多人指出的那样,这是因为许多 LINQ 方法的所谓 延迟执行。例如,Enumerable.Select 方法 documentation 状态

This method is implemented by using deferred execution. The immediate return value is an object that stores all the information that is required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its GetEnumerator method directly or by using foreach in Visual C# or For Each in Visual Basic.

Enumerable.ToList documentation 包含

The ToList<TSource>(IEnumerable<TSource>) method forces immediate query evaluation and returns a List that contains the query results. You can append this method to your query in order to obtain a cached copy of the query results.

所以 XDocument.LoadToList 调用期间真正为每个文件名执行。我想这涵盖了 why 部分。

and how best to handle this error? I'd like to have access to the working XDocuments still, if possible.

我不知道 "best" 在这种情况下是什么意思,但是如果您想忽略错误并包含 "working XDocuments",那么您可以使用类似这样的东西

var xDocs = fileNames.Select(fileName =>
{
    try { return XDocument.Load(fileName); }
    catch { return null; }
});

然后在处理列表时追加 .Where(doc => doc != null) 或考虑 null 个文档。