CA1010: Kolekce musí implementovat obecné rozhraní

Vlastnost Hodnota
ID pravidla CA1010
Název Kolekce musí implementovat obecné rozhraní
Kategorie Návrh
Oprava způsobující chybu nebo chybu způsobující chybu Nenarušující
Povoleno ve výchozím nastavení v .NET 8 No

Příčina

Typ implementuje rozhraní, ale neimplementuje System.Collections.IEnumerableSystem.Collections.Generic.IEnumerable<T> rozhraní a obsahující sestavení cílí na .NET. Toto pravidlo ignoruje typy, které implementují System.Collections.IDictionary.

Ve výchozím nastavení toto pravidlo sleduje jenom externě viditelné typy, ale dá se konfigurovat. Můžete také nakonfigurovat další rozhraní, která vyžadují implementaci obecného rozhraní.

Popis pravidla

Použitelnost kolekce lze rozšířit implementací jednoho z rozhraní obecné kolekce. Tuto kolekci pak můžete použít k naplnění obecných typů kolekcí, jako jsou například následující:

Jak opravit porušení

Chcete-li opravit porušení tohoto pravidla, implementujte jedno z následujících obecných rozhraní kolekce:

Kdy potlačit upozornění

Je bezpečné potlačit upozornění z tohoto pravidla; použití kolekce však bude omezenější.

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 CA1010
// The code that's violating the rule is on this line.
#pragma warning restore CA1010

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.CA1010.severity = none

Další informace naleznete v tématu Jak potlačit upozornění analýzy kódu.

Konfigurace kódu pro analýzu

Pomocí následujících možností můžete nakonfigurovat, pro které části základu kódu se má toto pravidlo spouštět.

Tyto možnosti můžete nakonfigurovat jenom pro toto pravidlo, pro všechna pravidla, která se vztahují, nebo pro všechna pravidla v této kategorii (Návrh), na která platí. Další informace naleznete v tématu Možnosti konfigurace pravidla kvality kódu.

Zahrnutí konkrétních povrchů rozhraní API

Na základě přístupnosti můžete nakonfigurovat, na kterých částech základu kódu se má toto pravidlo spouštět. Pokud chcete například určit, že pravidlo by se mělo spouštět jenom na neveřejné ploše rozhraní API, přidejte do souboru .editorconfig v projektu následující pár klíč-hodnota:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Další požadovaná obecná rozhraní

Seznam názvů rozhraní (oddělených |) můžete nakonfigurovat pomocí požadovaného obecného plně kvalifikovaného rozhraní (odděleného ).->

Povolené formáty rozhraní:

  • Pouze název rozhraní (zahrnuje všechna rozhraní s názvem bez ohledu na typ nebo obor názvů).
  • Plně kvalifikované názvy ve formátu ID dokumentace symbolu s volitelnou T: předponou.

Příklady:

Hodnota možnosti Shrnutí
dotnet_code_quality.CA1010.additional_required_generic_interfaces = ISomething->System.Collections.Generic.IEnumerable`1 Očekává se také System.Collections.Generic.IEnumerable<T>implementace všech typů, které implementují ISomething bez ohledu na jeho obor názvů .
dotnet_code_quality.CA1010.additional_required_generic_interfaces = T:System.Collections.IDictionary->T:System.Collections.Generic.IDictionary`2 Všechny typy, které implementují System.Collections.IDictionary , se mají implementovat System.Collections.Generic.IDictionary<TKey,TValue>také .

Příklad

Následující příklad ukazuje třídu, která je odvozena z negenerické CollectionBase třídy a porušuje toto pravidlo.

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

Pokud chcete opravit porušení tohoto pravidla, udělejte jednu z těchto věcí:

Oprava implementací rozhraní

Následující příklad řeší porušení implementací těchto obecných rozhraní: IEnumerable<T>, ICollection<T>a 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()
        {
        }
    }
}

Oprava změnou základní třídy

Následující příklad opraví porušení tím, že změní základní třídu kolekce z ne generické CollectionBase třídy na obecný Collection<T> (Collection(Of T) v jazyce Visual Basic).

public class Book
{
    public Book()
    {
    }
}

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

Změna základní třídy již vydané třídy se považuje za zásadní změnu stávajících příjemců.

Viz také