在lambda表达式中没有捕获到InvalidOperationException

时间:2014-06-26 15:37:55

标签: c# exception lambda

关于InvalidOperationException的使用,我正在追踪XmlSerializer.Deserialize。奇怪的是,当我向它提供格式错误的XML时,它确实会在该行上抛出InvalidOperationException,但它不会被catch块捕获。

我的第一个假设是lambda中的异常处理有些奇怪,但我在搜索时找不到任何结论。

有人有想法吗?

另外,请注意,此代码适用于非格式错误的XML。此外,InvalidOperationException位于System

的相同名称空间中
    XElement xmlElement = GetElement("users");
    XmlSerializer deserializer = new XmlSerializer(typeof(User));        
    try
            {
                return xmlElement.Descendants("user").Select(x => (User)deserializer.Deserialize(x.CreateReader()));
            }
            catch (InvalidOperationException e)
            {
                //XmlSerializer almost always throws this ambiguous exception but its inner exception is much more explicit
                //creating a new exception with the message of the old to ensure there isn't a circular throw-catch of InvalidOperationException
                throw new XmlException(e.InnerException.Message);
            }

1 个答案:

答案 0 :(得分:2)

我不知道如何使用返回值,但Select是惰性的,只有在枚举结果集合时才执行lambda。我认为这就是catch不起作用的原因 - 在抛出异常时,它已经超出了catch块。

ToArray添加到最后应强制它立即执行:

return xmlElement.Descendants("user").Select(x => (User)deserializer.Deserialize(x.CreateReader())).ToArray();

引自MSDN

  

此方法通过使用延迟执行来实现。立即返回值是一个对象,它存储执行操作所需的所有信息。在通过直接调用其GetEnumerator方法或在Visual C#中使用foreach或在Visual Basic中使用For Each来枚举对象之前,不会执行此方法表示的查询。