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:
- System.Collections.Generic.List<T>
- System.Collections.Generic.Queue<T>
- System.Collections.Generic.Stack<T>
Schendingen oplossen
Als u een schending van deze regel wilt oplossen, implementeert u een van de volgende algemene verzamelingsinterfaces:
- System.Collections.Generic.IEnumerable<T>
- System.Collections.Generic.ICollection<T>
- System.Collections.Generic.IList<T>
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:
- Implementeer de algemene interface.
- Wijzig de basisklasse in een type dat al zowel de algemene als niet-algemene interfaces implementeert, zoals de
Collection<T>
klasse.
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.
Gerelateerde regels
- CA1005: Vermijd overmatige parameters voor algemene typen
- CA1000: Geen statische leden declareren voor algemene typen
- CA1002: algemene lijsten niet beschikbaar maken
- CA1003: Algemene gebeurtenis-handler-exemplaren gebruiken