IEnumerable vs Ilist - IsNullOrEmpty扩展方法

时间:2015-02-02 11:19:51

标签: c# extension-methods ienumerable ilist isnullorempty

我有一个自定义集合IList<user>作为用户。当我试图检查users是空还是空时,我没有获得任何情报帮助(如IsNullOrEmpty)所以我写了下面的扩展方法

public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
    {
        if (source.IsNullOrEmpty())
        {
            return true;
        }
        return false;
    }

令我惊讶的是,我发现IEnumberable有IsNullOrEmpty()。

根据我的知识IList延伸ICollection再次延伸IEnumerable,如果是这种情况,则IList应该支持IsNullOrEmpty

请纠正错误的地方。

2 个答案:

答案 0 :(得分:4)

IEnumerable<T>没有IsNullOrEmpty方法,它是您在上面写的扩展名。如果你打电话给它,你会得到StackOverflowException

你可以用这种方式实现它:

public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
{
    return source == null || !source.Any();
}

但重要的是要注意这种方法不是那么有用,甚至可以改善。因为Enumerable.Any将“使用”查询。因此,如果它不是内存中的集合,则必须调用GetEnumerator并开始枚举它,以便检查是否至少有一个项目。有时,如果对象被枚举(例如在.NET中的File.ReadLines&lt; = 4),该对象将被取消对象,如果您稍后再尝试使用它将导致ObjectDisposedException

此方法具有不必要的副作用的另一个示例是序列是过滤(...Where(x => Compute(x, random.Next())))的查询。此查询可能每次都会产生不同的结果。引用Marc Gravell的评论:“ IEnumerable不应该被认为是可重复的”。

在Linq-To-Sql或Linq-To-Entities中,您每次IsNullOrEmpty次呼叫都会调用数据库。

答案 1 :(得分:0)

正如评论中提到的@Marc Gravel“IEnumerable<T>不应该被认为是可重复的”。假设您的源IEnumerable是从datareader创建的。你只有一次机会迭代它。如果您只消耗它只是为了看它是否为空,那么您将无法再次访问这些记录。也许您想为IList编写扩展方法(如果需要),而不是IEnumerable

public static bool IsNullOrEmpty<T>(this IList<T> source)
{
    return source == null || source.Count == 0;
}