我已经看到了一些有关 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 调用,但这也不起作用。我错过了什么?
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}");
}