CA1010: Auflistungen müssen eine generische Schnittstelle implementieren
TypeName |
CollectionsShouldImplementGenericInterface |
CheckId |
CA1010 |
Kategorie |
Microsoft.Design |
Unterbrechende Änderung |
Nicht unterbrechend |
Ursache
Ein extern sichtbarer Typ implementiert die System.Collections.IEnumerable-Schnittstelle, jedoch nicht die System.Collections.Generic.IEnumerable<T>-Schnittstelle, und das Ziel der enthaltenden Assembly ist .NET Framework 2.0.Bei dieser Regel werden Typen ignoriert, die System.Collections.IDictionary implementieren.
Regelbeschreibung
Um die Verwendbarkeit einer Auflistung zu erweitern, implementieren Sie eine der generischen Auflistungsschnittstellen.Anschließend kann die Auflistung verwendet werden, um generische Auflistungstypen wie die folgenden aufzufüllen:
Behandeln von Verstößen
Um einen Verstoß gegen diese Regel zu korrigieren, implementieren Sie eine der folgenden generischen Auflistungsschnittstellen:
Wann sollten Warnungen unterdrückt werden?
Warnungen dieser Regel können gefahrlos unterdrückt werden; allerdings wird damit die Verwendbarkeit der Auflistung eingeschränkt.
Beispiel für einen Verstoß
Beschreibung
Im folgenden Beispiel wird eine Klasse (Referenztyp) veranschaulicht, die von der nicht generischen CollectionBase-Klasse abgeleitet wird, die gegen diese Regel verstößt.
Code
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);
}
}
}
Kommentare
Um einen Verstoß gegen diese Regel zu beheben, sollten Sie entweder die generischen Schnittstellen implementieren oder die Basisklasse in einen Typ ändern, durch den sowohl generische als auch nicht generische Schnittstellen bereits implementiert werden, z. B. die Collection<T>-Klasse.
Korrektur durch Änderung der Basisklasse
Beschreibung
Im folgenden Beispiel wird der Verstoß korrigiert, indem die Basisklasse der Auflistung von der nicht generischen CollectionBase-Klasse in die generische Collection<T>-Klasse (Collection(Of T) in Visual Basic) geändert wird.
Code
using System;
using System.Collections.ObjectModel;
namespace Samples
{
public class Book
{
public Book()
{
}
}
public class BookCollection : Collection<Book>
{
public BookCollection()
{
}
}
}
Kommentare
Wenn die Basisklasse einer bereits freigegebenen Klasse geändert wird, gilt dies als unterbrechende Änderung vorhandener Consumer.
Korrektur durch Schnittstellenimplementierung
Beschreibung
Im folgenden Beispiel wird der Verstoß korrigiert, indem folgende generische Schnittstellen implementiert werden: IEnumerable<T>, ICollection<T> und IList<T> (IEnumerable(Of T), ICollection(Of T) und IList(Of T) in Visual Basic).
Code
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()
{
}
}
}
}
Verwandte Regeln
CA1005: Übermäßige Anzahl von Parametern in generischen Typen vermeiden
CA1000: Statische Member nicht in generischen Typen deklarieren
CA1002: Generische Listen nicht verfügbar machen
CA1006: Generische Typen in Membersignaturen nicht schachteln
CA1004: Generische Methoden müssen den Typparameter angeben
CA1003: Generische Ereignishandlerinstanzen verwenden
CA1007: Nach Möglichkeit Generika verwenden