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í:
- System.Collections.Generic.List<T>
- System.Collections.Generic.Queue<T>
- System.Collections.Generic.Stack<T>
Jak opravit porušení
Chcete-li opravit porušení tohoto pravidla, implementujte jedno z následujících obecných rozhraní kolekce:
- System.Collections.Generic.IEnumerable<T>
- System.Collections.Generic.ICollection<T>
- System.Collections.Generic.IList<T>
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í:
- Implementujte obecné rozhraní.
- Změňte základní třídu na typ, který již implementuje obecná i ne generická rozhraní, jako
Collection<T>
je například třída.
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ů.
Související pravidla
- CA1005: Vyhněte se nadbytečným parametrům na obecných typech
- CA1000: Nedeklarujte statické členy v obecných typech
- CA1002: Nezveřejňujte obecné seznamy
- CA1003: Použijte instance obecných obslužných rutin události