CA1010: Le raccolte devono implementare un'interfaccia generica
TypeName |
CollectionsShouldImplementGenericInterface |
CheckId |
CA1010 |
Category |
Microsoft.Design |
Breaking Change |
Non sostanziale |
Causa
Un tipo visibile esternamente implementa l'interfaccia System.Collections.IEnumerable ma non l'interfaccia System.Collections.Generic.IEnumerable<T> e l'assembly che lo contiene è destinato a .NET Framework 2.0.La regola ignora i tipi che implementano System.Collections.IDictionary.
Descrizione della regola
Per ampliare la possibilità di utilizzo di una raccolta, implementare una delle interfacce di raccolte generiche.La raccolta potrà poi essere utilizzata per inserire dati in tipi di raccolte generiche come la seguente:
Come correggere le violazioni
Per correggere una violazione di questa regola, implementare una delle seguenti interfacce di raccolte generiche:
Esclusione di avvisi
L'esclusione di un avviso da questa regola è sicura; la raccolta, tuttavia, avrà un utilizzo più limitato.
Esempio di violazione
Descrizione
Nell'esempio seguente viene mostrata una classe (tipo di riferimento) che deriva dalla classe non generica CollectionBase che viola questa regola.
Codice
using System;
using System.Collections;
namespace Samples
{
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);
}
}
}
Commenti
Per correggere questo tipo di violazione è necessario implementare le interfacce generiche o impostare la classe di base su un tipo che implementa già interfacce generiche e non generiche, ad esempio la classe Collection<T>.
Correzione tramite modifica della classe base
Descrizione
Nell'esempio riportato di seguito viene corretta la violazione impostando la classe di base della raccolta impostata sulla classe non generica CollectionBase sulla classe generica Collection<T> (Collection(Of T) in Visual Basic).
Codice
using System;
using System.Collections.ObjectModel;
namespace Samples
{
public class Book
{
public Book()
{
}
}
public class BookCollection : Collection<Book>
{
public BookCollection()
{
}
}
}
Commenti
La modifica della classe base di una classe già rilasciata è considerata una modifica sostanziale che può causare interruzioni per i consumer esistenti.
Correzione tramite implementazione di interfaccia
Descrizione
Nell'esempio riportato di seguito viene corretta la violazione implementando le seguenti interfacce generiche: IEnumerable<T>, ICollection<T> e IList<T> (IEnumerable(Of T), ICollection(Of T) e IList(Of T) in Visual Basic).
Codice
using System;
using System.Collections;
using System.Collections.Generic;
namespace Samples
{
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 { return (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()
{
}
}
}
}
Regole correlate
CA1005: Evitare un uso eccessivo di parametri nei tipi generici
CA1000: Non dichiarare membri statici su tipi generici
CA1002: Non esporre elenchi generici
CA1006: Non annidare tipi generici nelle firme dei membri
CA1004: I metodi generici devono fornire parametri di tipo
Ca1003: Utilizzare istanze di gestori eventi generici
CA1007: Utilizzare generics dove appropriato