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.