为什么Count()方法使用“ checked”关键字?


23

在查看Count和Count()之间的区别时,我想看一看的源代码Count()。我看到了以下代码片段,我想知道为什么checked关键字是必需/必需的:

int num = 0;
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
    while (enumerator.MoveNext())
    {
        num = checked(num + 1);
    }
    return num;
}

源代码:

// System.Linq.Enumerable
using System.Collections;
using System.Collections.Generic;

public static int Count<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
    }
    ICollection<TSource> collection = source as ICollection<TSource>;
    if (collection != null)
    {
        return collection.Count;
    }
    IIListProvider<TSource> iIListProvider = source as IIListProvider<TSource>;
    if (iIListProvider != null)
    {
        return iIListProvider.GetCount(onlyIfCheap: false);
    }
    ICollection collection2 = source as ICollection;
    if (collection2 != null)
    {
        return collection2.Count;
    }
    int num = 0;
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            num = checked(num + 1);
        }
        return num;
    }
}

2
.NET 4.0尚无此检查,而4.5有。这样做很可能是为了避免WinRT迭代器出现问题,请注意,它们使用uint。
汉斯(Hans)Passant

Answers:


35

因为它不希望在(绝对不太可能)的事件中返回负数(序列中有超过20亿个项目),或者在非负数但错误的情况下(甚至更不可能)返回负数序列中有超过40亿个项目。checked将检测溢出条件。


1
@DavidMårtenssonC#默认为unchecked; 不过,可以checked通过编译器开关将其默认转换为全局级别-但坦率地说,我很少看到它使用过,因此,我认为建议C#“通常”以checked模式运行是非常错误的。还要注意,unsafe它与unchecked
Marc Gravell

1
这对我来说是个新闻,我在编写之前就在项目中对其进行了测试,而C#抱怨溢出,直到我对其添加未检查的内容为止?编辑:找到了我所看到的答案“对于常量表达式(可以在编译时完全评估的表达式),始终检查默认上下文。除非将常量表达式显式放置在未检查的上下文中,否则在编译期间会发生溢出表达式的实时评估会导致编译时错误。”
DavidMårtensson

@DavidMårtensson啊,是的-很好的细微差别;我说的是运行时;正如您所说:编译时间不同
Marc Gravell

但是编译时间不适用于该帖子的示例,因此我的评论不正确,因此已将其删除。
DavidMårtensson,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.