LINQ 方法链接和精细错误处理
本文关键字:错误 处理 方法 链接 LINQ | 更新日期: 2023-09-27 18:36:30
我有一个可以通过方法链接非常整齐地编写的方法:
return viewer.ServerReport.GetParameters()
.Single(p => p.Name == Convention.Ssrs.RegionParamName)
.ValidValues
.Select(v => v.Value);
但是,我希望能够在每个点进行一些检查,因为如果任何链接方法返回意外结果,我希望提供有用的诊断信息。
为了实现这一点,我需要打破我所有的链条,并用一个if
块跟踪每个调用。它使代码的可读性大大降低。
理想情况下,我希望能够编织一些链式方法调用,这将允许我在每个点处理意外结果(例如,抛出一个有意义的异常,例如,如果第一个方法返回空集合,则抛出new ConventionException("The report contains no parameter")
)。谁能提出一种简单的方法来实现这样的事情?
编辑:
这是使用@JeffreyZhao答案的结果:
return viewer.ServerReport.GetParameters()
.Assert(result => result.Any(), "The report contains no parameter")
.SingleOrDefault(p => p.Name == Convention.Ssrs.RegionParamName)
.Assert(result => result != null, "The report does not contain a region parameter")
.ValidValues
.Select(v => v.Value)
.Assert(result => result.Any(), "The region parameter in the report does not contain any valid value");
也许你可以使用这种方法。
static T Check<T>(this T value)
{
if (...) throw ...;
return value;
}
然后:
xxx.Single(...).Check().Select(...).Check()...
更新:
您甚至可以:
static T Validate<T>(this T value, Func<T, bool> validate, string errorMessage)
{
if (!validate(value))
throw new ValidationFailedException(errorMessage);
return value;
}
然后:
xxxx.Single()
.Validate(v => v > 0, "Must be greater than zero")
.NextStep()
.Validate(...);
您可以使用局部变量轻松地将流程拆分为单独的步骤:
var result1 = viewer.ServerReport.GetParameters();
var result2 = result1.Single(p => p.Name == Convention.Ssrs.RegionParamName);
var result3 = result2.ValidValues;
var result4 = result3.Select(v => v.Value);
return result4;
现在,您可以在步骤之间执行所需的任何检查。
但请注意,某些结果实际上并没有做任何工作。例如,最后一步不会生成列表作为结果,它会生成一个从ValidValues
读取的枚举对象,因此该步骤中的任何错误都会在您使用结果时发生,而不是在此方法中。您可能希望在某些步骤结束时添加.ToList()
以实现结果。
考虑使用代码协定(例如,将后置条件添加到ServerReport.GetParameters
以确保方法不会返回空集合)。它们允许以更优雅的方式做你想做的事情,而不是编写自己的检查逻辑。
class ReportParameter { }
class ServerReport
{
public ReportParameter[] GetParameters()
{
Contract.Ensures(Contract.Result<ReportParameter[]>() != null && Contract.Result<ReportParameter[]>().Length > 0,
Resource1.Oops);
// here's some logic to build parameters array...
return new ReportParameter[0];
}
}
用法:
// Oops! I need at least one parameter!
var parameters = new ServerReport().GetParameters();