Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
CA1851: Možné více výčtů
| Vlastnost | Hodnota |
|---|---|
| ID pravidla | CA1851 |
| Název | Možné více výčtů IEnumerable kolekce |
| Kategorie | Výkon |
| Oprava způsobující chybu nebo chybu způsobující chybu | Nenarušující |
| Zavedená verze | .NET 7 |
| Povoleno ve výchozím nastavení v .NET 10 | No |
Příčina
Zjistilo se více výčtů IEnumerable kolekce.
Popis pravidla
Kolekce typu IEnumerable nebo <> má schopnost odložit výčet při generování. Mnoho metod LINQ, například Select, používá odložené spuštění. Výčet se spustí, když se kolekce předá do metody výčtu LINQ, jako je ElementAt, nebo použit v příkazu pro každý příkaz. Výsledek výčtu se nevypočítá jednou a ukládá se do mezipaměti, jako je Lazy.
Pokud je samotná operace výčtu nákladná, například dotaz do databáze, více výčtů by poškodilo výkon programu.
Pokud má operace výčtu vedlejší účinky, může mít několik výčtů za následek chyby.
Jak opravit porušení
Pokud je podkladovým typem kolekce IEnumerable jiný typ, například List nebo Array, je bezpečné převést kolekci na základní typ a opravit tak diagnostiku.
Porušení:
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
Oprava:
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
Pokud základní typ IEnumerable kolekce používá implementaci založenou na iterátoru (například pokud je vygenerována metodami LINQ, jako Select je nebo pomocí klíčového slova výnos ), můžete opravit porušení tím, že kolekci materializujete. Tím se ale přiděluje další paměť.
Příklad:
Porušení:
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
Oprava:
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
Konfigurace přizpůsobených metod výčtu a metod řetězu LINQ
Ve výchozím nastavení jsou všechny metody v System.Linq oboru názvů zahrnuty do oboru analýzy. Můžete přidat vlastní metody, které vyčíslí IEnumerable argument do oboru nastavením enumeration_methods možnosti v souboru .editorconfig .
Do oboru analýzy můžete také přidat přizpůsobené metody řetězu LINQ (tj. metody přebírají IEnumerable argument a vrátit novou IEnumerable instanci) nastavením linq_chain_methods možnosti v souboru .editorconfig .
Konfigurace výchozího předpokladu metod přebírá IEnumerable parametry
Ve výchozím nastavení se předpokládá, že všechny přizpůsobené metody, které přijímají IEnumerable argument, nejsou výčet argumentu. Můžete to změnit nastavením assume_method_enumerates_parameters možnosti v souboru .editorconfig .
Kdy potlačit upozornění
Toto upozornění je bezpečné potlačit, pokud je podkladovým typem IEnumerable kolekce jiný typ, Listnapříklad Array nebo nebo pokud jste si jisti, že metody, které kolekci nevyčtouIEnumerable, ji nevyčtou.
Potlačení upozornění
Pokud chcete pouze potlačit jedno porušení, přidejte do zdrojového souboru direktivy preprocesoru, abyste pravidlo zakázali a znovu povolili.
#pragma warning disable CA1851
// The code that's violating the rule is on this line.
#pragma warning restore CA1851
Pokud chcete pravidlo pro soubor, složku nebo projekt zakázat, nastavte jeho závažnost v none konfiguračním souboru.
[*.{cs,vb}]
dotnet_diagnostic.CA1851.severity = none
Další informace naleznete v tématu Jak potlačit upozornění analýzy kódu.