Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
CA1851: Olası birden çok koleksiyon numaralandırması
| Özellik | Değer |
|---|---|
| Kural Kimliği | CA1851 |
| Başlık | Olası birden çok koleksiyon numaralandırması IEnumerable |
| Kategori | Performans |
| Hataya neden olan veya bozulmayan düzeltme | Hataya neden olmayan |
| Tanıtılan sürüm | .NET 7 |
| .NET 10'da varsayılan olarak etkin | Hayır |
Neden
Bir IEnumerable koleksiyonun birden çok numaralandırması algılandı.
Kural açıklaması
IEnumerable veya IEnumerable<> türünde bir koleksiyon, oluşturulduğunda numaralandırmayı erteleme özelliğine sahiptir. Select gibi birçok LINQ yöntemi ertelenen yürütmeyi kullanır. Numaralandırma, koleksiyon ElementAt gibi bir LINQ numaralandırma yöntemine geçirildiğinde veya her deyim için bir içinde kullanıldığında başlar. Numaralandırma sonucu bir kez hesaplanmaz ve Gecikmeli gibi önbelleğe alınır.
Numaralandırma işleminin kendisi pahalıysa (örneğin, bir veritabanındaki sorgu), birden çok sabit listesi programın performansına zarar verebilir.
Numaralandırma işleminin yan etkileri varsa, birden çok numaralandırma hatalara neden olabilir.
İhlalleri düzeltme
Koleksiyonunuzun IEnumerable temel türü veya Listgibi Array başka bir türse, tanılamayı düzeltmek için koleksiyonu temel alınan türüne dönüştürmek güvenlidir.
İhlal:
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
Düzeltme:
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
Koleksiyonun IEnumerable temel türü yineleyici tabanlı bir uygulama kullanıyorsa (örneğin, yield anahtar sözcüğünü kullanarak Select veya gibi LINQ yöntemleri tarafından oluşturulduysa), koleksiyonu gerçekleştirerek ihlali düzeltebilirsiniz. Ancak, bu ek bellek ayırır.
Örneğin:
İhlal:
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
Düzeltme:
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
Özelleştirilmiş numaralandırma yöntemlerini ve LINQ zincir yöntemlerini yapılandırma
Varsayılan olarak, ad alanı içindeki System.Linq tüm yöntemler analiz kapsamına dahil edilir. .editorconfigIEnumerableayarlayarakenumeration_methods, bir bağımsız değişkeni kapsama numaralandıran özel yöntemler ekleyebilirsiniz.
Ayrıca bir .editorconfig dosyasındaki seçeneği ayarlayarak IEnumerable analiz kapsamına özelleştirilmiş LINQ zincir yöntemleri (yani yöntemler bağımsız IEnumerable değişken alır ve yeni linq_chain_methods bir örnek döndürür) ekleyebilirsiniz.
Parametreleri alan IEnumerable yöntemlerin varsayılan varsayımını yapılandırma
Varsayılan olarak, bağımsız IEnumerable değişkeni kabul eden tüm özelleştirilmiş yöntemlerin bağımsız değişkeni listelemediği varsayılır. Bir .editorconfig dosyasında seçeneğini assume_method_enumerates_parametersayarlayarak bunu değiştirebilirsiniz.
Uyarıların ne zaman bastırılması gerekiyor?
Koleksiyonun temel alınan türü veya IEnumerablegibi List başka bir türse Array veya koleksiyon alan IEnumerable yöntemlerin bunu listelemediğinden eminseniz, bu uyarıyı gizlemeniz güvenlidir.
Uyarıyı gizleme
Yalnızca tek bir ihlali engellemek istiyorsanız, kuralı devre dışı bırakmak ve sonra yeniden etkinleştirmek için kaynak dosyanıza ön işlemci yönergeleri ekleyin.
#pragma warning disable CA1851
// The code that's violating the rule is on this line.
#pragma warning restore CA1851
Bir dosya, klasör veya projenin kuralını devre dışı bırakmak için, yapılandırma dosyasındaki önem derecesini noneolarak ayarlayın.
[*.{cs,vb}]
dotnet_diagnostic.CA1851.severity = none
Daha fazla bilgi için bkz . Kod analizi uyarılarını gizleme.