拥有IEnumerable.First(...)实现而没有隐式捕获的闭包(ReSharper)

时间:2017-06-22 16:49:20

标签: c# linq lambda closures

我基本上想要创建自己的LINQ .First(item => ...)和.Single(item => ...)实现,只有对象,它会抛出一个带有意义消息的异常日志文件:

var items = new List<Item>();
// fill items...
var itemIdToFind = 1234; // not supposed to be constant
var itemFound = items.First(
    i => i.ID==1234,
    () => new NotFoundException("Item " + itemIdToFind + " not found in items"));

实施是这样的:

internal static class MyExtendedLinq
{
    public static T First<T, TEx>(this IEnumerable<T> elements, Func<T, bool> predicate, Func<TEx> notFoundErrorFunc)
        where TEx : Exception
    {
        var firstOnly = elements.Where(predicate).Take(1).ToArray();
        // don't confuse found default value with default due to element not found - not FirstOrDefault!.
        if (firstOnly.Length == 1) 
        {
            return firstOnly[0];
        }
        throw notFoundErrorFunc(); // don't care for null func in example
    }
}

这为ReSharper提供了隐式捕获的闭包警告,包括Exception lambda和谓词函数。

特别是对于Func谓词,我认为常规的LINQ First(谓词)实现没有区别,它没有显示此警告。

我不希望来自常规First(prediate)方法的无意义的InvalidOperationExceptions,让人们搜索天数,其中缺少预期的东西。

1 个答案:

答案 0 :(得分:1)

你的情况有所不同,你有两个不同的lambda,每个lambda都关闭不同的变量。 Enumerable.First只有一个lambda,所以它无法做到。

现在,你不需要关心关于这个警告,因为这两个委托都没有长寿(也不会比任何变量都长),所以没有问题