具有无投保证的IEnumerable Extensions

Eri*_*ich 4 c# null extension-methods exception

就个人而言,作为客户端,我是C#中IEnumerable/List扩展方法的流畅接口语法的粉丝.也就是说,我更喜欢这样的语法:

    public void AddTheseGuysToSomeLocal(IEnumerable<int> values)
    {
        values.ToList().ForEach(v => _someLocal += v);
    }
Run Code Online (Sandbox Code Playgroud)

而不是像foreach循环这样的控制结构.我发现一眼就能更容易地进行心理处理.问题是,如果客户端传递给我一个null参数,我的代码将生成空引用异常.

让我们假设我不想将空枚举视为例外 - 我希望这会导致一些本地原样 - 我会添加一个空保护.但是,根据我的口味,这在语法上有点嘈杂,如果你在一个流畅的界面中将这些链接在一起,并且中期结果也可以为空,那么噪音就会增加.

因此,我创建了一个名为SafeEnumerableExtensions的类,它通过将空值视为空枚举(列表)来提供无抛出保证.示例方法包括:

    //null.ToList() returns empty list
    public static List<T> SafeToList<T>(this IEnumerable<T> source)
    {
        return (source ?? new List<T>()).ToList();
    }

    //x.SafeForEach(y) is a no-op for null x or null y
    //This is a shortcut that should probably go in a class called SafeListExtensions later
    public static void SafeForEach<T>(this List<T> source, Action<T> action)
    {
        var myAction = action ?? new Action<T>(t => { });
        var mySource = source ?? new List<T>();
        mySource.ForEach(myAction);
    }

    public static void SafeForEach<T>(this IEnumerable<T> source, Action<T> action)
    {
        SafeToList(source).SafeForEach(action);            
    }
Run Code Online (Sandbox Code Playgroud)

现在,我的原始方法比没有空保护更漂亮,但同样安全,因为null导致无操作:

    public void AddTheseGuysToSomeLocal(IEnumerable<int> values)
    {
        values.ForEach(v => _someLocal += v);
    }
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是双重的.(1)我假设我不是那么原始,不是第一个想到这个的人 - 有没有人知道是否有现有的图书馆做这个或类似的东西?并且(2)有没有人使用过这个图书馆或实施这样的计划并且经历了不愉快的后果,否则任何人都可以预见到做这样的事情会产生不愉快的后果?这甚至是个好主意吗?

(我在检查重复项时确实发现了这个问题,但我不想在客户端中明确地执行此检查 - 我希望扩展类隐式执行此操作而不会使用额外的方法调用来打扰客户端)

Bro*_*ass 7

并且(2)有没有人使用过这个图书馆或实施这样的计划并且经历了不愉快的后果,否则任何人都可以预见到做这样的事情会产生不愉快的后果?这甚至是个好主意吗?

我个人认为这是一个坏主意.在大多数情况下,传递null枚举或null Func可能不是预期的.

你正在"修复"这个问题,这个问题可能会导致后来看似无关的问题.相反,我宁愿在这种情况下抛出异常,以便您在早期的代码中找到此问题("快速失败").