CA1851: A gyűjtemény lehetséges több enumerálása IEnumerable
Tulajdonság | Érték |
---|---|
Szabályazonosító | CA1851 |
Cím | A gyűjtemény lehetséges több enumerálása IEnumerable |
Kategória | Teljesítmény |
A javítás kompatibilitástörő vagy nem törik | Nem törés |
Bevezetett verzió | .NET 7 |
Alapértelmezés szerint engedélyezve a .NET 8-ban | Nem |
Ok
Egy gyűjtemény több enumerálását észlelte IEnumerable
.
Szabály leírása
Az IEnumerable vagy az IEnumerable<T> típusú gyűjtemények képesek az enumerálás elhalasztására a létrehozáskor. Számos LINQ-metódus, például a Kiválasztás, halasztott végrehajtást használ. Az enumerálás akkor kezdődik, amikor a gyűjtemény egy LINQ enumerálási metódusba kerül, például az ElementAt metódusba, vagy egy-egy utasításban használatos. Az enumerálási eredmény nem egyszer lesz kiszámítva, és gyorsítótárazva lesz, például Lazy.
Ha maga az enumerálási művelet költséges, például egy adatbázisba irányuló lekérdezés, több enumerálás is rontaná a program teljesítményét.
Ha az enumerálási műveletnek vannak mellékhatásai, több enumerálás is hibákat okozhat.
Szabálysértések kijavítása
Ha a gyűjtemény alapjául szolgáló típus IEnumerable
valamilyen más típusú, például List
vagy Array
, akkor a diagnosztikához biztonságosan átalakíthatja a gyűjteményt a mögöttes típusra.
Szabálysértés:
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
Javítás:
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
Ha a IEnumerable
gyűjtemény alapjául szolgáló típus iterátoralapú implementációt használ (például ha linq metódusok, például Select a hozam kulcsszó használatával hozza létre), a gyűjtemény materializálásával kijavíthatja a szabálysértést. Ez azonban további memóriát foglal le.
Például:
Szabálysértés:
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
Javítás:
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
Testreszabott enumerálási módszerek és LINQ-lánc metódusok konfigurálása
Alapértelmezés szerint a System.Linq névtér összes metódusa szerepel az elemzési hatókörben. A .editorconfig fájl beállításával egyéni metódusokat adhat hozzá, amelyek számba adnak egy IEnumerable
argumentumot a enumeration_methods
hatókörben.
Testre szabott LINQ-lánc metódusokat is hozzáadhat (vagyis a metódusok argumentumot IEnumerable
vesznek fel, és egy új IEnumerable
példányt adnak vissza) az elemzési hatókörbe egy .editorconfig fájlban lévő beállítás beállításávallinq_chain_methods
.
A metódusok alapértelmezett feltételezésének konfigurálása paraméterekkel IEnumerable
Alapértelmezés szerint az argumentumot IEnumerable
elfogadó összes testreszabott metódus feltételezi, hogy nem veszi számba az argumentumot. Ezt egy .editorconfig fájl beállításával assume_method_enumerates_parameters
módosíthatja .
Mikor kell letiltani a figyelmeztetéseket?
Ezt a figyelmeztetést nyugodtan letilthatja, ha a IEnumerable
gyűjtemény alapjául szolgáló típus más típusú, például List
vagy Array
, vagy ha biztos abban, hogy a gyűjteményt IEnumerable
használó metódusok nem számba veszik.
Figyelmeztetés mellőzése
Ha csak egyetlen szabálysértést szeretne letiltani, adjon hozzá előfeldolgozási irányelveket a forrásfájlhoz a szabály letiltásához és újbóli engedélyezéséhez.
#pragma warning disable CA1851
// The code that's violating the rule is on this line.
#pragma warning restore CA1851
Ha le szeretné tiltani egy fájl, mappa vagy projekt szabályát, állítsa annak súlyosságát none
a konfigurációs fájlban.
[*.{cs,vb}]
dotnet_diagnostic.CA1851.severity = none
További információ: Kódelemzési figyelmeztetések letiltása.
Kapcsolódó információk
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: