Bagikan melalui


CA1851: Kemungkinan beberapa enumerasi dari kumpulan IEnumerable

Properti Nilai
ID Aturan CA1851
Judul Kemungkinan beberapa enumerasi IEnumerable koleksi
Golongan Performa
Perbaikan bersifat disruptif atau non-disruptif Non-disruptif
Versi yang diperkenalkan .NET 7
Diaktifkan secara default di .NET 9 No

Penyebab

Terdeteksi beberapa enumerasi dari kumpulan IEnumerable.

Deskripsi aturan

Kumpulan jenis IEnumerable atau > memiliki kemampuan untuk menukar enumerasi saat dihasilkan. Banyak metode LINQ, seperti Pilih, menggunakan eksekusi yang ditangguhkan. Enumerasi dimulai ketika koleksi diteruskan ke metode enumerasi LINQ, seperti ElementAt, atau digunakan dalam untuk setiap pernyataan. Hasil enumerasi tidak dihitung sekali dan di-cache, seperti Malas.

Jika operasi enumerasi itu sendiri mahal, misalnya, kueri ke dalam database, beberapa enumerasi akan merusak performa program.

Jika operasi enumerasi memiliki efek samping, beberapa enumerasi dapat menghasilkan bug.

Cara memperbaiki pelanggaran

Jika jenis yang mendasar dari koleksi Anda IEnumerable adalah beberapa jenis lain, seperti List atau Array, aman untuk mengonversi koleksi ke jenis yang mendasar untuk memperbaiki diagnostik.

Pelanggaran:

public void MyMethod(IEnumerable<int> input)
{
    var count = input.Count();
    foreach (var i in input) { }
}
Public Sub MyMethod(input As IEnumerable(Of Integer))
    Dim count = input.Count()
    For Each i In input
    Next
End Sub

Perbaikan:

public void MyMethod(IEnumerable<int> input)
{
    // If the underlying type of 'input' is List<int>
    var inputList = (List<int>)input;
    var count = inputList.Count();
    foreach (var i in inputList) { }
}
Public Sub MyMethod(input As IEnumerable(Of Integer))
    ' If the underlying type of 'input' is array
    Dim inputArray = CType(input, Integer())
    Dim count = inputArray.Count()
    For Each i In inputArray
    Next
End Sub

Jika jenis IEnumerable koleksi yang mendasar menggunakan implementasi berbasis iterator (misalnya, jika dihasilkan oleh metode LINQ seperti Select atau dengan menggunakan kata kunci hasil ), Anda dapat memperbaiki pelanggaran dengan mewujudkan koleksi. Namun, hal ini mengalokasikan memori tambahan.

Contohnya:

Pelanggaran:

public void MyMethod()
{
    var someStrings = GetStrings().Select(i => string.Concat("Hello"));

    // It takes 2 * O(n) to complete 'Count()' and 'Last()' calls, where 'n' is the length of 'someStrings'.
    var count = someStrings.Count();
    var lastElement = someStrings.Last();
}
Public Sub MyMethod()
    Dim someStrings = GetStrings().Select(Function(i) String.Concat(i, "Hello"))

    ' It takes 2 * O(n) to complete 'Count()' and 'Last()' calls, where 'n' is the length of 'someStrings'.
    Dim count = someStrings.Count()
    Dim lastElement = someStrings.Last()
End Sub

Perbaikan:

public void MyMethod()
{
    var someStrings = GetStrings().Select(i => string.Concat("Hello"));
    // Materialize it into an array.
    // Note: This operation would allocate O(n) memory,
    // and it takes O(n) time to finish, where 'n' is the length of 'someStrings'.
    var someStringsArray = someStrings.ToArray()

    // It takes 2 * O(1) to complete 'Count()' and 'Last()' calls.
    var count = someStringsArray.Count();
    var lastElement = someStringsArray.Last();
}
Public Sub MyMethod()
    Dim someStrings = GetStrings().Select(Function(i) String.Concat(i, "Hello"))
    ' Materialize it into an array.
    ' Note: This operation would allocate O(n) memory,
    ' and it takes O(n) time to finish, where 'n' is the length of 'someStrings'.
    Dim someStringsArray = someStrings.ToArray()

    ' It takes 2 * O(1) to complete 'Count()' and 'Last()' calls.
    Dim count = someStrings.Count()
    Dim lastElement = someStrings.Last()
End Sub

Mengonfigurasi metode enumerasi dan metode rantai LINQ yang disesuaikan

Secara default, semua metode dalam namespace System.Linq disertakan dalam cakupan analisis. Anda dapat menambahkan metode kustom yang menghitung argumen IEnumerable ke dalam cakupan dengan mengatur opsi enumeration_methods dalam file .editorconfig.

Anda juga dapat menambahkan metode rantai LINQ yang disesuaikan (yaitu, metode mengambil argumen IEnumerable dan mengembalikan instans IEnumerable baru) ke cakupan analisis dengan mengatur opsi linq_chain_methods dalam file .editorconfig.

Mengonfigurasi asumsi default metode mengambil parameter IEnumerable

Secara default, semua metode yang disesuaikan yang menerima argumen IEnumerable diasumsikan tidak menghitung argumen. Anda dapat mengubah ini dengan mengatur opsi assume_method_enumerates_parameters dalam file .editorconfig.

Kapan harus menekan peringatan

Aman untuk menekan peringatan ini jika jenis IEnumerable koleksi yang mendasar adalah beberapa jenis lain seperti List atau Array, atau jika Anda yakin bahwa metode yang mengambil IEnumerable koleksi tidak menghitungnya.

Menyembunyikan peringatan

Jika Anda hanya ingin menyembunyikan satu pelanggaran, tambahkan arahan praprosedur ke file sumber Anda untuk dinonaktifkan lalu aktifkan kembali aturannya.

#pragma warning disable CA1851
// The code that's violating the rule is on this line.
#pragma warning restore CA1851

Untuk menonaktifkan aturan untuk file, folder, atau proyek, atur tingkat keparahannya ke none dalam file konfigurasi.

[*.{cs,vb}]
dotnet_diagnostic.CA1851.severity = none

Untuk informasi selengkapnya, lihat Cara menyembunyikan peringatan analisis kode.

Lihat juga