应该这样做:
public static bool ContainsExactlyOneItem<T>(this IEnumerable<T> source)
{
using (IEnumerator<T> iterator = source.GetEnumerator())
{
// Check we've got at least one item
if (!iterator.MoveNext())
{
return false;
}
// Check we've got no more
return !iterator.MoveNext();
}
}
您可以进一步省略,但我不建议您这样做:
public static bool ContainsExactlyOneItem<T>(this IEnumerable<T> source)
{
using (IEnumerator<T> iterator = source.GetEnumerator())
{
return iterator.MoveNext() && !iterator.MoveNext();
}
}
这是一种很时髦的技巧,但可能不应该在生产代码中使用。只是不够清楚。 && 运算符在 LHS 中的副作用是 RHS 正常工作所必需的,这一事实令人讨厌......虽然很有趣 ;)
编辑:我刚刚看到你想出了完全相同的东西,但长度是任意的。不过,您的最终退货声明是错误的 - 它应该是退货!en.MoveNext()。这是一个完整的方法,具有更好的名称 (IMO)、参数检查和优化 ICollection/ICollection<T>:
public static bool CountEquals<T>(this IEnumerable<T> source, int count)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count",
"count must not be negative");
}
// We don't rely on the optimizations in LINQ to Objects here, as
// they have changed between versions.
ICollection<T> genericCollection = source as ICollection<T>;
if (genericCollection != null)
{
return genericCollection.Count == count;
}
ICollection nonGenericCollection = source as ICollection;
if (nonGenericCollection != null)
{
return nonGenericCollection.Count == count;
}
// Okay, we're finally ready to do the actual work...
using (IEnumerator<T> iterator = source.GetEnumerator())
{
for (int i = 0; i < count; i++)
{
if (!iterator.MoveNext())
{
return false;
}
}
// Check we've got no more
return !iterator.MoveNext();
}
}
编辑:现在对于功能爱好者来说,CountEquals 的递归形式(请不要使用它,它只是为了笑):
public static bool CountEquals<T>(this IEnumerable<T> source, int count)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count",
"count must not be negative");
}
using (IEnumerator<T> iterator = source.GetEnumerator())
{
return IteratorCountEquals(iterator, count);
}
}
private static bool IteratorCountEquals<T>(IEnumerator<T> iterator, int count)
{
return count == 0 ? !iterator.MoveNext()
: iterator.MoveNext() && IteratorCountEquals(iterator, count - 1);
}
编辑:请注意,对于 LINQ to SQL 之类的东西,您应该使用简单的Count() 方法 - 因为这样可以在数据库中完成,而不是在获取实际结果之后。