CA1010: 컬렉션은 제네릭 인터페이스를 구현해야 합니다.
속성 | 값 |
---|---|
규칙 ID | CA1010 |
제목 | 컬렉션은 제네릭 인터페이스를 구현해야 합니다. |
범주 | 디자인 |
수정 사항이 주요 변경인지 여부 | 주요 변경 아님 |
.NET 9에서 기본적으로 사용 | 아니요 |
원인
형식은 System.Collections.IEnumerable인터페이스를 구현하지만 System.Collections.Generic.IEnumerable<T> 인터페이스를 구현하지 않으며 포함하는 어셈블리는 .NET을 대상으로 합니다. 이 규칙은 System.Collections.IDictionary를 구현하는 형식을 무시합니다.
기본적으로 이 규칙은 외부에 표시되는 형식만 확인하지만 이는 구성 가능합니다. 제네릭 인터페이스 구현을 요구하도록 추가 인터페이스를 구성할 수도 있습니다.
규칙 설명
컬렉션의 유용성을 높이려면 제네릭 컬렉션 인터페이스 중 하나를 구현합니다. 그러면 컬렉션을 사용하여 제네릭 컬렉션 형식을 채울 수 있습니다.
- System.Collections.Generic.List<T>
- System.Collections.Generic.Queue<T>
- System.Collections.Generic.Stack<T>
위반 문제를 해결하는 방법
이 규칙 위반 문제를 해결하려면 다음 제네릭 컬렉션 인터페이스 중 하나를 구현합니다.
- System.Collections.Generic.IEnumerable<T>
- System.Collections.Generic.ICollection<T>
- System.Collections.Generic.IList<T>
경고를 표시하지 않는 경우
이 규칙에서는 경고를 표시하지 않아도 됩니다. 그러나 컬렉션을 사용하는 것은 더 제한적입니다.
경고 표시 안 함
단일 위반만 표시하지 않으려면 원본 파일에 전처리기 지시문을 추가하여 규칙을 사용하지 않도록 설정한 후 다시 사용하도록 설정합니다.
#pragma warning disable CA1010
// The code that's violating the rule is on this line.
#pragma warning restore CA1010
파일, 폴더 또는 프로젝트에 대한 규칙을 사용하지 않도록 설정하려면 구성 파일에서 심각도를 none
으로 설정합니다.
[*.{cs,vb}]
dotnet_diagnostic.CA1010.severity = none
자세한 내용은 방법: 코드 분석 경고 표시 안 함을 참조하세요.
분석할 코드 구성
다음 옵션을 사용하여 이 규칙이 실행될 코드베이스 부분을 구성합니다.
이 규칙, 적용되는 모든 규칙 또는 적용되는 이 범주(디자인)의 모든 규칙에 대해 이러한 옵션을 구성할 수 있습니다. 자세한 내용은 코드 품질 규칙 구성 옵션을 참조하세요.
특정 API 화면 포함
접근성을 기반으로 이 규칙을 실행할 코드베이스의 파트를 구성할 수 있습니다. 예를 들어 규칙이 퍼블릭이 아닌 API 표면에서만 실행되도록 지정하려면 프로젝트의 .editorconfig 파일에 다음 키-값 쌍을 추가합니다.
dotnet_code_quality.CAXXXX.api_surface = private, internal
추가 필수 제네릭 인터페이스
|
로 구분된 인터페이스 이름 목록을 ->
로 구분된 필수 제네릭 정규화된 인터페이스로 구성할 수 있습니다.
허용되는 인터페이스 형식:
- 인터페이스 이름만(포함하는 형식 또는 네임스페이스와 관계없이 해당 이름의 모든 인터페이스 포함).
- 기호의 설명서 ID 형식에 있는 정규화된 이름(선택적
T:
접두사 포함)
예:
옵션 값 | 요약 |
---|---|
dotnet_code_quality.CA1010.additional_required_generic_interfaces = ISomething->System.Collections.Generic.IEnumerable`1 |
네임스페이스와 관계없이 ISomething 을 구현하는 모든 형식은 System.Collections.Generic.IEnumerable<T>도 구현해야 합니다. |
dotnet_code_quality.CA1010.additional_required_generic_interfaces = T:System.Collections.IDictionary->T:System.Collections.Generic.IDictionary`2 |
System.Collections.IDictionary를 구현하는 모든 형식은 System.Collections.Generic.IDictionary<TKey,TValue>도 구현되어야 합니다. |
예시
다음 예제에서는 제네릭이 아닌 CollectionBase
클래스에서 파생되고 이 규칙을 위반하는 클래스를 보여 줍니다.
public class Book
{
public Book()
{
}
}
public class BookCollection : CollectionBase
{
public BookCollection()
{
}
public void Add(Book value)
{
InnerList.Add(value);
}
public void Remove(Book value)
{
InnerList.Remove(value);
}
public void Insert(int index, Book value)
{
InnerList.Insert(index, value);
}
public Book? this[int index]
{
get { return (Book?)InnerList[index]; }
set { InnerList[index] = value; }
}
public bool Contains(Book value)
{
return InnerList.Contains(value);
}
public int IndexOf(Book value)
{
return InnerList.IndexOf(value);
}
public void CopyTo(Book[] array, int arrayIndex)
{
InnerList.CopyTo(array, arrayIndex);
}
}
이 규칙 위반 문제를 해결하려면 다음 중 하나를 수행합니다.
- 제네릭 인터페이스를 구현합니다.
- 기본 클래스를
Collection<T>
클래스와 같은 제네릭 인터페이스 및 제네릭이 아닌 인터페이스 모두를 이미 구현하는 형식으로 변경합니다.
인터페이스 구현으로 수정
다음 예제에서는 IEnumerable<T>, ICollection<T>, IList<T> 제네릭 인터페이스를 구현하여 위반을 수정합니다.
public class Book
{
public Book()
{
}
}
public class BookCollection : CollectionBase, IList<Book?>
{
public BookCollection()
{
}
int IList<Book?>.IndexOf(Book? item)
{
return this.List.IndexOf(item);
}
void IList<Book?>.Insert(int location, Book? item)
{
}
Book? IList<Book?>.this[int index]
{
get => (Book?)this.List[index];
set { }
}
void ICollection<Book?>.Add(Book? item)
{
}
bool ICollection<Book?>.Contains(Book? item)
{
return true;
}
void ICollection<Book?>.CopyTo(Book?[] array, int arrayIndex)
{
}
bool ICollection<Book?>.IsReadOnly
{
get { return false; }
}
bool ICollection<Book?>.Remove(Book? item)
{
if (InnerList.Contains(item))
{
InnerList.Remove(item);
return true;
}
return false;
}
IEnumerator<Book> IEnumerable<Book?>.GetEnumerator()
{
return new BookCollectionEnumerator(InnerList.GetEnumerator());
}
private class BookCollectionEnumerator : IEnumerator<Book>
{
private IEnumerator _Enumerator;
public BookCollectionEnumerator(IEnumerator enumerator)
{
_Enumerator = enumerator;
}
public Book Current
{
get { return (Book)_Enumerator.Current; }
}
object IEnumerator.Current
{
get { return _Enumerator.Current; }
}
public bool MoveNext()
{
return _Enumerator.MoveNext();
}
public void Reset()
{
_Enumerator.Reset();
}
public void Dispose()
{
}
}
}
기본 클래스 변경으로 수정
다음 예제에서는 컬렉션의 기본 클래스를 제네릭이 아닌 CollectionBase
클래스에서 제네릭 Collection<T>
(Visual Basic에서 Collection(Of T)
) 클래스로 변경하여 위반을 수정합니다.
public class Book
{
public Book()
{
}
}
public class BookCollection : Collection<Book>
{
public BookCollection()
{
}
}
이미 릴리스된 클래스의 기본 클래스를 변경하는 것은 기존 소비자의 호환성이 손상되는 변경으로 간주됩니다.
관련 규칙
- CA1005: 제네릭 형식에 매개 변수를 너무 많이 사용하지 마십시오.
- CA1000: 정적 멤버를 제네릭 형식으로 선언하지 마십시오.
- CA1002: 제네릭 목록을 노출하지 마십시오.
- CA1003: 제네릭 이벤트 처리기 인스턴스를 사용하십시오.
참고 항목
.NET