Las colecciones deben implementar la interfaz genérica
Actualización: noviembre 2007
TypeName |
CollectionsShouldImplementGenericInterface |
Identificador de comprobación |
CA1010 |
Category |
Microsoft.Design |
Cambio problemático |
No problemático |
Motivo
Un tipo visible externamente implementa la interfaz System.Collections.IEnumerable pero no la interfaz System.Collections.Generic.IEnumerable<T>, y el ensamblado que lo contiene está diseñado para .NET Framework 2.0. Esta regla omite los tipos que implementan System.Collections.IDictionary.
Descripción de la regla
Para ampliar la utilidad de una colección, implemente una de las interfaces de colección genéricas. A continuación, la colección se puede utilizar para rellenar tipos de colecciones genéricas, como los siguientes:
Cómo corregir infracciones
Para corregir una infracción de esta regla, implemente una de las interfaces de colección genéricas siguientes:
Cuándo suprimir advertencias
Es seguro suprimir una advertencia de esta regla; sin embargo, la colección tendrá un uso más limitado.
Infracción del ejemplo
Descripción
El ejemplo siguiente muestra una clase (tipo de referencia) que deriva de la clase no genérica CollectionBase, que infringe esta regla.
Código
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);
}
}
}
Comentarios
Para corregir una infracción de esta infracción, debe implementar las interfaces genéricas o cambiar la clase base a un tipo que implemente tanto las interfaces genéricas como las no genéricas, como por ejemplo la clase Collection<T>.
Corregir por cambio de clase base
Descripción
En el ejemplo siguiente se corrige la infracción cambiando la clase base de la colección de la clase no genérica CollectionBase a la clase genérica Collection<T> (Collection(Of T) en Visual Basic).
Código
using System;
using System.Collections.ObjectModel;
namespace Samples
{
public class Book
{
public Book()
{
}
}
public class BookCollection : Collection<Book>
{
public BookCollection()
{
}
}
}
Comentarios
Si se cambia la clase base de una clase que ya se ha liberado, se considera un cambio importante para los consumidores.
Corregir por implementación de interfaz
Descripción
En el siguiente ejemplo se corrige la infracción implementado estas interfaces genéricas IEnumerable<T>, ICollection<T> y IList<T> (IEnumerable(Of T), ICollection(Of T) y IList(Of T) en Visual Basic).
Código
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()
{
}
}
}
}
Reglas relacionadas
Evite el exceso de parámetros en los tipos genéricos
No declare miembros estáticos en tipos genéricos
No anide los tipos genéricos en firmas de miembro
Los métodos genéricos deben proporcionar el parámetro de tipo
Utilice instancias de control de eventos genéricas
Utilice genéricos cuando resulte apropiado