我正在考虑以流利的样式Where子句使用功能块谓词来记录一些结果,例如:
var bar = SomeEnumerable.Where(i =>
{
if(...)
{
return true;
}
else
{
//Log "failure" to in-memory List<T>
return false;
}
}).Select(...);
我还有其他方法可以捕获这种不会带来副作用的东西吗?
我一直在考虑使用Linq扩展方法,该方法可以将其结果“添加”到多个后续方法中。已经有这样的运算符了吗?
如果可能的话,我同意100%保持远离Linq的副作用。
答案 0 :(得分:0)
这是您的代码,随您便吧。
如果您了解向LINQ添加副作用的含义,即说它不适用于SQL查询,并且您知道只有在调用.ToList()
或类似方法后才能运行它。
去吧!
在大多数情况下,日志记录是一个非常安全的副作用,如果您需要遥测中的信息,这取决于您。我可以将其设置为方法而不是lambda,以便以后的读者可以清楚地看到其意图。
答案 1 :(得分:0)
在这种情况下,您要做的并不是真正过滤序列,而是将项目分组为两个不同的组之一。比Where
更好的运算符。
var validatedItems = SomeEnumerable.ToLookup(item => IsValid(item));
foreach(var invalidItem in validatedItems[false])
{
LogFailure(invalidItem);
}
var bar = validatedItem[true].Select(...);
请注意,这里的ToLookup
会急切地评估源序列和您的验证逻辑。如果您想将验证推迟到以后(同时还要避免序列的多次枚举,您可能要做想要这样做,因为它正在执行验证逻辑),这会使该过程变得很复杂。