关于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);
}
答案 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来枚举对象之前,不会执行此方法表示的查询。