Freigeben über


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ß

Beschreibungen

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);
        }
    }
}

Kommentar

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

Beschreibungen

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()        
        {        
        }    
    }
}

Kommentar

Wenn die Basisklasse einer bereits freigegebenen Klasse geändert wird, gilt dies als unterbrechende Änderung vorhandener Consumer.

Korrektur durch Schnittstellenimplementierung

Beschreibungen

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

Siehe auch

Referenz

Generika (C#-Programmierhandbuch)