Delen via


CA1010: Verzamelingen moeten algemene interface implementeren

Eigenschappen Weergegeven als
Regel-id CA1010
Titel Verzamelingen moeten algemene interface implementeren
Categorie Ontwerpen
Oplossing is brekend of niet-brekend Niet-brekend
Standaard ingeschakeld in .NET 9 Nee

Oorzaak

Een type implementeert de System.Collections.IEnumerable interface, maar implementeert de System.Collections.Generic.IEnumerable<T> interface niet en het met de assemblydoelen .NET. Met deze regel worden typen genegeerd die worden geïmplementeerd System.Collections.IDictionary.

Deze regel kijkt standaard alleen naar extern zichtbare typen, maar dit kan worden geconfigureerd. U kunt ook aanvullende interfaces configureren om te vereisen dat een algemene interface wordt geïmplementeerd.

Beschrijving van regel

Als u de bruikbaarheid van een verzameling wilt uitbreiden, implementeert u een van de algemene verzamelingsinterfaces. Vervolgens kan de verzameling worden gebruikt om algemene verzamelingstypen te vullen, zoals de volgende:

Schendingen oplossen

Als u een schending van deze regel wilt oplossen, implementeert u een van de volgende algemene verzamelingsinterfaces:

Wanneer waarschuwingen onderdrukken

Het is veilig om een waarschuwing van deze regel te onderdrukken; het gebruik van de verzameling is echter beperkter.

Een waarschuwing onderdrukken

Als u slechts één schending wilt onderdrukken, voegt u preprocessorrichtlijnen toe aan uw bronbestand om de regel uit te schakelen en vervolgens opnieuw in te schakelen.

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

Als u de regel voor een bestand, map of project wilt uitschakelen, stelt u de ernst none ervan in op het configuratiebestand.

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

Zie Codeanalysewaarschuwingen onderdrukken voor meer informatie.

Code configureren om te analyseren

Gebruik de volgende opties om te configureren op welke onderdelen van uw codebase deze regel moet worden uitgevoerd.

U kunt deze opties configureren voor alleen deze regel, voor alle regels waarop deze van toepassing is, of voor alle regels in deze categorie (ontwerp) waarop deze van toepassing is. Zie de configuratieopties voor de codekwaliteitsregel voor meer informatie.

Specifieke API-oppervlakken opnemen

U kunt instellen op welke onderdelen van uw codebase deze regel moet worden uitgevoerd, op basis van hun toegankelijkheid. Als u bijvoorbeeld wilt opgeven dat de regel alleen moet worden uitgevoerd op het niet-openbare API-oppervlak, voegt u het volgende sleutel-waardepaar toe aan een .editorconfig-bestand in uw project:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Aanvullende vereiste algemene interfaces

U kunt de lijst met interfacenamen (gescheiden door |) configureren met de vereiste algemene volledig gekwalificeerde interface (gescheiden door ->).

Toegestane interface-indelingen:

  • Alleen interfacenaam (inclusief alle interfaces met de naam, ongeacht het type of de naamruimte).
  • Volledig gekwalificeerde namen in de documentatie-id-indeling van het symbool met een optioneel T: voorvoegsel.

Voorbeelden:

Optiewaarde Samenvatting
dotnet_code_quality.CA1010.additional_required_generic_interfaces = ISomething->System.Collections.Generic.IEnumerable`1 Alle typen die worden geïmplementeerd ISomething , ongeacht de naamruimte, worden naar verwachting ook geïmplementeerd System.Collections.Generic.IEnumerable<T>.
dotnet_code_quality.CA1010.additional_required_generic_interfaces = T:System.Collections.IDictionary->T:System.Collections.Generic.IDictionary`2 Alle typen die worden geïmplementeerd System.Collections.IDictionary , worden naar verwachting ook geïmplementeerd System.Collections.Generic.IDictionary<TKey,TValue>.

Opmerking

In het volgende voorbeeld ziet u een klasse die is afgeleid van de niet-generieke CollectionBase klasse en deze regel schendt.

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

Ga op een van de volgende manieren te werk om een schending van deze regel op te lossen:

Oplossing per interface-implementatie

In het volgende voorbeeld wordt de schending opgelost door deze algemene interfaces te implementeren: IEnumerable<T>, ICollection<T>en 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()
        {
        }
    }
}

Oplossing op basis van wijziging van basisklasse

In het volgende voorbeeld wordt de schending opgelost door de basisklasse van de verzameling van de niet-algemene CollectionBase klasse te wijzigen in de klasse Algemeen Collection<T> (Collection(Of T) in Visual Basic).

public class Book
{
    public Book()
    {
    }
}

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

Het wijzigen van de basisklasse van een reeds uitgebrachte klasse wordt beschouwd als een belangrijke wijziging voor bestaande consumenten.

Zie ook