IEnumerable.Count()可以返回一个负数吗?

时间:2018-03-27 00:13:19

标签: c# .net linq

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没有指明任何可能发生的情况。

只是想知道是否有人对此发生过任何经验或有任何相关信息。

由于

2 个答案:

答案 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)

实际上,CountIEnumerable都没有定义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,因此这是一个坏主意。