IEnumerable 与 Ilist - IsNullOrEmpty 扩展方法
IEnumerable vs Ilist - IsNullOrEmpty extension method
我有一个自定义集合 IList<user>
作为用户。当我试图检查 users
是否为 null 或空时,我没有得到任何情报帮助(如 IsNullOrEmpty
)所以我写了下面的扩展方法
public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
{
if (source.IsNullOrEmpty())
{
return true;
}
return false;
}
令我惊讶的是,我发现 IEnumberable 有 IsNullOrEmpty()。
据我所知,IList
扩展了 ICollection
,后者又扩展了 IEnumerable
,如果是这样,那么 IList
应该支持 IsNullOrEmpty
。
不对的地方请指正
IEnumerable<T>
没有 IsNullOrEmpty
方法,它是你上面写的扩展。如果你调用它,你会得到一个 WhosebugException
.
你可以这样实现:
public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
{
return source == null || !source.Any();
}
但需要注意的是,这种方法并没有多大帮助,甚至可能会变得更糟。因为 Enumerable.Any
将 "consume" 查询。因此,如果它不是内存中的集合,则它必须调用 GetEnumerator
并开始枚举它,以便检查是否至少有一项。有时,如果对象被枚举(如 .NET <= 4 中的 File.ReadLines
),该对象将被撤销,如果您稍后再次尝试使用它,将导致 ObjectDisposedException
。
此方法具有不良副作用的另一个示例是序列是一个过滤查询 (...Where(x => Compute(x, random.Next()))
)。此查询可能每次都会产生不同的结果。引用 Marc Gravell 的评论:“IEnumerable 不应被假定为可重复的”。
在 Linq-To-Sql 或 Linq-To-Entities 中,您将在每次 IsNullOrEmpty
调用时调用数据库。
正如@Marc Gravel 在评论中提到的“IEnumerable<T>
不应假定为可重复的”。假设您的源 IEnumerable
是从数据读取器创建的。你只有一次机会迭代它。如果您消耗那唯一的机会只是为了查看它是否为空,您将无法再次访问记录。也许您想为 IList
而不是 IEnumerable
.
编写扩展方法(如果需要)
public static bool IsNullOrEmpty<T>(this IList<T> source)
{
return source == null || source.Count == 0;
}
我有一个自定义集合 IList<user>
作为用户。当我试图检查 users
是否为 null 或空时,我没有得到任何情报帮助(如 IsNullOrEmpty
)所以我写了下面的扩展方法
public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
{
if (source.IsNullOrEmpty())
{
return true;
}
return false;
}
令我惊讶的是,我发现 IEnumberable 有 IsNullOrEmpty()。
据我所知,IList
扩展了 ICollection
,后者又扩展了 IEnumerable
,如果是这样,那么 IList
应该支持 IsNullOrEmpty
。
不对的地方请指正
IEnumerable<T>
没有 IsNullOrEmpty
方法,它是你上面写的扩展。如果你调用它,你会得到一个 WhosebugException
.
你可以这样实现:
public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
{
return source == null || !source.Any();
}
但需要注意的是,这种方法并没有多大帮助,甚至可能会变得更糟。因为 Enumerable.Any
将 "consume" 查询。因此,如果它不是内存中的集合,则它必须调用 GetEnumerator
并开始枚举它,以便检查是否至少有一项。有时,如果对象被枚举(如 .NET <= 4 中的 File.ReadLines
),该对象将被撤销,如果您稍后再次尝试使用它,将导致 ObjectDisposedException
。
此方法具有不良副作用的另一个示例是序列是一个过滤查询 (...Where(x => Compute(x, random.Next()))
)。此查询可能每次都会产生不同的结果。引用 Marc Gravell 的评论:“IEnumerable 不应被假定为可重复的”。
在 Linq-To-Sql 或 Linq-To-Entities 中,您将在每次 IsNullOrEmpty
调用时调用数据库。
正如@Marc Gravel 在评论中提到的“IEnumerable<T>
不应假定为可重复的”。假设您的源 IEnumerable
是从数据读取器创建的。你只有一次机会迭代它。如果您消耗那唯一的机会只是为了查看它是否为空,您将无法再次访问记录。也许您想为 IList
而不是 IEnumerable
.
public static bool IsNullOrEmpty<T>(this IList<T> source)
{
return source == null || source.Count == 0;
}