C#IEnumerable.Count(IEnumerable<TSource>)
和IEnumerable.Count(IEnumerable<TSource>, Func<TSource,Boolean>)
都返回类型int
,暗示它可以返回小于零的值。它没有意义,但如果类型为int
,理论上结果可能是负值。
IEnumerable<string> list = GetMyList();
int listCount = list.Count();
// is it more correct to do this:
if(listCount <= 0)
{
DoSomething();
}
else
{
DoSomethingElse();
}
// or this:
if(listCount == 0)
{
DoSomething();
}
else if (listCount > 0)
{
DoSomethingElse();
}
else
{
// but this branch will never be hit
throw new Exception();
}
我无法在网上找到关于这是否真的可以发生的任何信息,Documentation for Enumerable.Count没有指明任何可能发生的情况。
只是想知道是否有人对此发生过任何经验或有任何相关信息。
由于
答案 0 :(得分:3)
返回数据类型的目的不是暗示一系列数字。虽然它自然会设置一个硬性上限和下限(有点......见LongCount),但这只是类型兼容性和普遍性的副作用。
考虑数组的Rank属性。最大值为32.但我们不将其存储为字节或短。我们将它存储在一个int中。为什么?我们不需要所有范围。但是建议:它们很快(它们与寄存器大小和内存映射很好地对齐),按照惯例,It is easier to work with other libraries if you work with ints。此外,int
数据类型为CLS-compliant(意味着任何实现CLR的语言都必须支持它),但uint32
不是。
返回具有特定范围的数字数据类型绝不意味着将使用整个范围。从IEnumerable.Count()
返回负值不仅形式不好,而且在语义上也是不正确的,因为计数必须显然返回cardinal number,它必须是整数和非负数。
答案 1 :(得分:1)
实际上,Count
和IEnumerable
都没有定义IEnumerable<T>
这样的方法,而是静态类System.Linq.Enumerable
。由于它是(static
)扩展方法,您根本无法覆盖或修改它。所以让我们看一下扩展方法:
public static int Count<TSource>(this IEnumerable<TSource> source)
{
if (source == null) throw Error.ArgumentNull("source");
ICollection<TSource> collectionoft = source as ICollection<TSource>;
if (collectionoft != null) return collectionoft.Count;
ICollection collection = source as ICollection;
if (collection != null) return collection.Count;
int count = 0;
using (IEnumerator<TSource> e = source.GetEnumerator()) {
checked {
while (e.MoveNext()) count++;
}
}
return count;
}
正如您所看到的,Count
永远返回负数的唯一方法是通过ICollection.Count
来实现Enumerable.Count()
,因为System.Linq.Enumerable
请参阅上文),或者使用完全相同的名称创建您自己的扩展方法并依赖extension-method resolution以便从public static class MyClass
{
public static int Count(this IEnumerable<T> src) { return -1; }
}
“隐藏”该方法:
docker exec
但是我看不出为什么要这样做的原因。
简而言之,方法可以返回一个负数。但是这样做会打破principle of least astonishment,因此这是一个坏主意。