我有一个自定义集合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
。
请纠正错误的地方。
答案 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;
}