具有无投保证的IEnumerable Extensions

时间:2011-12-03 23:59:46

标签: c# exception null extension-methods

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

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

与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);            
    }

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

    public void AddTheseGuysToSomeLocal(IEnumerable<int> values)
    {
        values.ForEach(v => _someLocal += v);
    }

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

(我在检查重复项时确实找到了this question,但我不想在客户端中明确地执行此检查 - 我希望扩展类隐式执行此操作而不用额外的方法调用来打扰客户端)

1 个答案:

答案 0 :(得分:7)

  

并且(2)有人使用过该库或实施了这样的方案   并且经历了令人不快的后果,否则任何人都可以预见到   做这样的事情会带来不愉快的后果吗?这甚至是一个   好主意?

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

你正在“修复”这个问题,这个问题可能会在未来的路上导致看似无关的问题。相反,我宁愿在这种情况下抛出异常,以便您早期在代码中找到此问题("Fail fast")。