Partilhar via


CA1010: Coleções devem implementar interface genérica

Propriedade valor
ID da regra CA1010
Cargo As coleções devem implementar interface genérica
Categoria Desenho
A correção está quebrando ou não quebrando Sem quebra
Habilitado por padrão no .NET 8 Não

Causa

Um tipo implementa a interface, mas não implementa a System.Collections.IEnumerableSystem.Collections.Generic.IEnumerable<T> interface e o assembly que contém o .NET. Esta regra ignora os tipos que implementam System.Collections.IDictionaryo .

Por padrão, essa regra examina apenas tipos visíveis externamente, mas isso é configurável. Você também pode configurar interfaces adicionais para exigir que uma interface genérica seja implementada.

Descrição da regra

Para ampliar a usabilidade de uma coleção, implemente uma das interfaces de coleção genéricas. Em seguida, a coleção pode ser usada para preencher tipos de coleção genéricos, como os seguintes:

Como corrigir violações

Para corrigir uma violação dessa regra, implemente uma das seguintes interfaces de coleção genéricas:

Quando suprimir avisos

É seguro suprimir uma advertência desta regra; no entanto, o uso da coleção será mais limitado.

Suprimir um aviso

Se você quiser apenas suprimir uma única violação, adicione diretivas de pré-processador ao seu arquivo de origem para desativar e, em seguida, reativar a regra.

#pragma warning disable CA1010
// The code that's violating the rule is on this line.
#pragma warning restore CA1010

Para desabilitar a regra de um arquivo, pasta ou projeto, defina sua gravidade como none no arquivo de configuração.

[*.{cs,vb}]
dotnet_diagnostic.CA1010.severity = none

Para obter mais informações, consulte Como suprimir avisos de análise de código.

Configurar código para análise

Use as opções a seguir para configurar em quais partes da base de código executar essa regra.

Você pode configurar essas opções apenas para esta regra, para todas as regras às quais ela se aplica ou para todas as regras nesta categoria (Design) às quais ela se aplica. Para obter mais informações, consulte Opções de configuração da regra de qualidade de código.

Incluir superfícies de API específicas

Você pode configurar em quais partes da sua base de código executar essa regra, com base em sua acessibilidade. Por exemplo, para especificar que a regra deve ser executada somente na superfície de API não pública, adicione o seguinte par chave-valor a um arquivo .editorconfig em seu projeto:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Interfaces genéricas adicionais necessárias

Você pode configurar a lista de nomes de interface (separados por ) com sua interface genérica totalmente qualificada (separada por |->).

Formatos de interface permitidos:

  • Somente nome da interface (inclui todas as interfaces com o nome, independentemente do tipo ou namespace que o contém).
  • Nomes totalmente qualificados no formato de ID de documentação do símbolo com um prefixo opcionalT:.

Exemplos:

Valor da opção Resumo
dotnet_code_quality.CA1010.additional_required_generic_interfaces = ISomething->System.Collections.Generic.IEnumerable`1 Espera-se que todos os tipos que implementam, independentemente de seu namespace, também implementem ISomethingSystem.Collections.Generic.IEnumerable<T>o .
dotnet_code_quality.CA1010.additional_required_generic_interfaces = T:System.Collections.IDictionary->T:System.Collections.Generic.IDictionary`2 Espera-se que todos os tipos que implementam também implementem System.Collections.IDictionarySystem.Collections.Generic.IDictionary<TKey,TValue>o .

Exemplo

O exemplo a seguir mostra uma classe que deriva da classe não genérica CollectionBase e viola essa regra.

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);
    }
}

Para corrigir uma violação dessa regra, siga um destes procedimentos:

Correção por implementação de interface

O exemplo a seguir corrige a violação implementando essas interfaces genéricas: IEnumerable<T>, ICollection<T>e 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()
        {
        }
    }
}

Correção por alteração de classe base

O exemplo a seguir corrige a violação alterando a classe base da coleção da classe não genérica para a classe genérica CollectionBaseCollection<T> (Collection(Of T) no Visual Basic).

public class Book
{
    public Book()
    {
    }
}

public class BookCollection : Collection<Book>
{
    public BookCollection()
    {
    }
}

Alterar a classe base de uma classe já lançada é considerado uma mudança significativa para os consumidores existentes.

Consulte também