lambda 内抛出的异常未被 catch 块捕获

问题描述 投票:0回答:1

我已经看到了一些有关 lambda 和异常的问题,但我仍然不明白我在代码中看到的行为。

        class MyObj
        {
            public object Prop1 { get; set; }
        }

        public void Get()
        {
            try
            {
                IEnumerable<MyObj> collection = new List<MyObj>() { new MyObj() };
                collection = collection.Where(x =>
                {
                    return x.Prop1.ToString() == "some value";
                });
            }
            catch (Exception ex)
            {
                throw new UriFormatException($"Invalid filter. Error details: {ex.Message}");
            }
        }

由于

Prop1
为 null,因此会抛出“对象引用未设置到对象实例”异常。但是,代码不会进入
catch
块。如果我添加一些尝试在
collection
块中使用
try
的代码,则当 lambda 中遇到异常时,将进入
catch
块。例如

                foreach (var c in collection)
                {
                    Console.WriteLine(c);
                }

如果执行 lambda 时出现任何异常,我希望输入 catch 块。我尝试编写一个命名函数来从 lambda 调用,但这也不起作用。我错过了什么?

c# lambda try-catch nullreferenceexception
1个回答
0
投票

Where
等 LINQ 运算符使用称为“延迟执行”的东西。这意味着当您调用它们时,它们实际上并不执行您提供给它们的 lambda:它们只是返回一个跟踪 lambda 和源的新查询。然后,当您尝试执行该查询时,它将开始评估 lambda。

因此,如果您想捕获查询委托中抛出的异常,则需要在 foreach 循环周围放置一个 try/catch,或者在其中放置类似

.ToList()
的内容以强制立即执行。

            try
            {
                var collection = new List<MyObj>() { new MyObj() }
                    .Where(x =>x.Prop1.ToString() == "some value")
                    .ToList();
            }
            catch (Exception ex)
            {
                throw new UriFormatException($"Invalid filter. Error details: {ex.Message}");
            }
© www.soinside.com 2019 - 2024. All rights reserved.