CA1010: Gli insiemi 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 un insieme, implementare una delle interfacce di insiemi generici. L'insieme potrà poi essere utilizzato per inserire dati in tipi di insiemi generici come il seguente:
Come correggere le violazioni
Per correggere una violazione di questa regola, implementare una delle seguenti interfacce di insiemi generici:
Esclusione di avvisi
L'esclusione di un avviso da questa regola è sicura; l'insieme, tuttavia, avrà un utilizzo più limitato.
Esempio di violazione
Oggetto di 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
Oggetto di descrizione
Nell'esempio riportato di seguito viene corretta la violazione impostando la classe di base dell'insieme 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
Oggetto di 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