Mengapa metode Hitung () menggunakan kata kunci "dicentang"?

23

Ketika saya mencari perbedaan antara Count dan Count () , saya berpikir untuk melirik kode sumber Count(). Saya melihat potongan kode berikut di mana saya bertanya-tanya mengapa checkedkata kunci itu diperlukan / dibutuhkan:

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

Kode sumber:

// 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;
    }
}
snr - Pasang kembali Monica
sumber
2
.NET 4.0 belum memiliki pemeriksaan ini, 4,5 belum. Membuatnya agak mungkin bahwa ini dilakukan untuk menghindari masalah dengan iterator WinRT , perhatikan bahwa mereka menggunakan uint.
Hans Passant

Jawaban:

35

Karena tidak ingin mengembalikan angka negatif dalam peristiwa (memang tidak mungkin) bahwa ada lebih dari 2 miliar item aneh dalam urutan - atau angka yang tidak negatif tetapi hanya salah dalam kasus (bahkan lebih tidak mungkin) bahwa ada lebih dari 4 miliar item aneh dalam urutannya. checkedakan mendeteksi kondisi overflow.

Marc Gravell
sumber
1
@ DavidMårtensson C # secara default adalah unchecked; itu dapat dibalik checkedsecara default di tingkat global melalui saklar kompiler, tetapi - tapi terus terang saya jarang melihat yang digunakan, jadi saya pikir sangat salah untuk menyarankan bahwa C # "biasanya" dijalankan dalam checkedmode; perhatikan juga yang unsafetidak memiliki interaksi denganunchecked
Marc Gravell
1
Itu adalah berita baru bagi saya, saya menguji ini dalam sebuah proyek sebelum menulis dan C # mengeluh tentang melimpah sampai saya menambahkan tidak dicentang di sekitarnya? Sunting: Ditemukan jawaban atas apa yang saya lihat "Untuk ekspresi konstan (ekspresi yang dapat sepenuhnya dievaluasi pada waktu kompilasi), konteks default selalu diperiksa. Kecuali jika ekspresi konstan secara eksplisit ditempatkan dalam konteks yang tidak dicentang, luapan yang terjadi selama kompilasi evaluasi waktu ekspresi menyebabkan kesalahan waktu kompilasi. "
David Mårtensson
@ DavidMårtensson ah, ya - bernuansa baik; Saya berbicara tentang runtime; seperti yang Anda katakan: waktu kompilasi berbeda
Marc Gravell
Tetapi waktu kompilasi tidak berlaku untuk contoh posting sehingga komentar saya salah dan saya telah menghapusnya.
David Mårtensson