CA1851: 컬렉션의
속성 | 값 |
---|---|
규칙 ID | CA1851 |
제목 | 컬렉션의 IEnumerable 가능한 여러 열거형 |
범주 | 성능 |
수정 사항이 주요 변경인지 여부 | 주요 변경 아님 |
도입된 버전 | .NET 7 |
.NET 9에서 기본적으로 사용 | 아니요 |
원인
컬렉션의 여러 열거형이 IEnumerable
검색되었습니다.
규칙 설명
IEnumerable 또는 IEnumerable<> 형식의 컬렉션은 생성될 때 열거를 연기할 수 있습니다. Select와 같은 많은 LINQ 메서드는 지연된 실행을 사용합니다. 컬렉션이 ElementAt와 같은 LINQ 열거형 메서드로 전달되거나 각 문에 사용되는 경우 열거형이 시작됩니다. 열거형 결과는 한 번 계산되지 않고 Lazy와 같이 캐시됩니다.
열거형 작업 자체가 비용이 많이 드는 경우(예: 데이터베이스에 대한 쿼리) 여러 열거형으로 인해 프로그램의 성능이 저하됩니다.
열거형 작업에 부작용이 있는 경우 여러 열거형으로 인해 버그가 발생할 수 있습니다.
위반 문제를 해결하는 방법
컬렉션의 IEnumerable
기본 형식이 다른 형식인 경우 컬렉션을 기본 형식으로 List
Array
변환하여 진단을 수정하는 것이 안전합니다.
위반:
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
Fix:
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
컬렉션의 IEnumerable
기본 형식이 반복기 기반 구현을 사용하는 경우(예: LINQ 메서드에서 Select 생성되거나 yield 키워드를 사용하여 생성된 경우) 컬렉션을 구체화하여 위반을 해결할 수 있습니다. 그러나 이렇게 하면 추가 메모리가 할당됩니다.
예시:
위반:
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
Fix:
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
사용자 지정된 열거형 메서드 및 LINQ 체인 메서드 구성
기본적으로 네임스페이스의 모든 메서드 System.Linq 는 분석 범위에 포함됩니다. .editorconfig 파일에서 옵션을 설정 IEnumerable
하여 인수를 범위에 열거 enumeration_methods
하는 사용자 지정 메서드를 추가할 수 있습니다.
.editorconfigIEnumerable
설정 IEnumerable
하여 사용자 지정된 LINQ 체인 메서드(즉, 메서드가 인수를 사용하고 linq_chain_methods
새 인스턴스를 반환)를 분석 범위에 추가할 수도 있습니다.
메서드 IEnumerable
테이크 매개 변수의 기본 가정 구성
기본적으로 인수를 허용하는 IEnumerable
모든 사용자 지정된 메서드는 인수를 열거하지 않는 것으로 간주됩니다. .editorconfigassume_method_enumerates_parameters
옵션을 설정 하여 이 옵션을 변경할 수 있습니다.
경고를 표시하지 않는 경우
컬렉션의 기본 형식 IEnumerable
이 다른 형식 List
인 경우 또는 Array
컬렉션을 사용하는 IEnumerable
메서드가 열거하지 않는 경우 이 경고를 표시하지 않는 것이 안전합니다.
경고 표시 안 함
단일 위반만 표시하지 않으려면 원본 파일에 전처리기 지시문을 추가하여 규칙을 사용하지 않도록 설정한 후 다시 사용하도록 설정합니다.
#pragma warning disable CA1851
// The code that's violating the rule is on this line.
#pragma warning restore CA1851
파일, 폴더 또는 프로젝트에 대한 규칙을 사용하지 않도록 설정하려면 none
에서 심각도를 으로 설정합니다.
[*.{cs,vb}]
dotnet_diagnostic.CA1851.severity = none
자세한 내용은 방법: 코드 분석 경고 표시 안 함을 참조하세요.
참고 항목
.NET