Catch块从不在LINQ语句内部启动

本文关键字:语句 内部 启动 LINQ Catch | 更新日期: 2023-09-27 18:15:57

我在Linq语句中有一些正在反序列化的数据:

var scheduledData = results
   .Where(o => o.Result.IsValid)
   .SelectMany(o => JsonConvert.DeserializeObject<List<CalendarJob>>(o.Result.Response))
   .ToList();

这是一个错误。我从未在调试器中看到此错误。返回的网页列出了一个500错误,显示了这一点。所以我添加了一些技巧:

var scheduledData = results
   .Where(o => o.Result.IsValid)
   .SelectMany(o => {
      try {
         return JsonConvert.DeserializeObject<List<CalendarJob>>(o.Result.Response);
      }
      catch {
         return new List<CalendarJob>();
      }
   })
   .ToList();

是的,这真的很难看。我只是这样做,这样我就可以在catch块上放置一个断点,这样我可以检查一些值。这不是我会留在原地的代码!:(

我在try块和catch块中的return语句上放置了一个断点。然后我执行代码。try语句命中,执行结束。catch块从不触发,在我的方法中也不会触发任何其他代码。

linq中是否应允许此catch块?我确实这么认为?

是的,我处于调试模式。是的,我已经清理和重建了。我的try块上的断点确实命中了。我可以检查即将反序列化的字符串的值,但该值不正确。是""。我的意思不是string.Empty,我的意思是字符串包含两个字节,并且都是双引号字符。我从中获取数据的服务没有返回好的数据。但我的catch块从未启动。

还有一件事需要注意。我把整个东西放在一个try...catch块中,catch块命中。只有LINQ内部的一个没有。

Catch块从不在LINQ语句内部启动

是的-这将按照您认为的方式工作。

唯一一次它不起作用的是你无法捕捉到的异常,比如StackOverflowException

为了证明这一点,只需在Visual Studio或Linqpad中执行以下代码,并观察断点是否被击中两次。

var list = new List<string>
{
    "a",
    "b"
};
list.Select(i =>
{
    try
    {
        return int.Parse(i);
    }
    catch
    {
        return 0; // Put a breakpoint here.
    }
}).ToList();

我找到了原因。内部JsonConvert不会引发Json无效的错误。相反,它返回null。所以我在JsonConvert周围的try...catch块什么也没做,因为没有什么可抓的。接下来,SelectMany期望返回一个List<>项,并试图枚举它以从中选择元素。因为它收到了null,所以在这里抛出了错误,而不是在Json转换中。这就是为什么外部try...catch接收到错误,而上面OP中的那个没有。

我接受了RB的回答,因为他回答了我最初的问题。这只是对任何未来发现者的解释。