Share via


Auflistungen müssen eine generische Schnittstelle implementieren

Aktualisiert: November 2007

     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:

Behandlung 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

Übermäßige Anzahl von Parametern in generischen Typen vermeiden

Statische Member nicht in generischen Typen deklarieren

Generische Listen nicht verfügbar machen

Generische Typen in Membersignaturen nicht schachteln

Generische Methoden müssen den Typparameter angeben

Generische Ereignishandlerinstanzen verwenden

Nach Möglichkeit Generika verwenden

Siehe auch

Referenz

Generika (C#-Programmierhandbuch)