Condividi tramite


CA1010: Le raccolte 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 una raccolta, implementare una delle interfacce di raccolte generiche.La raccolta potrà poi essere utilizzata per inserire dati in tipi di raccolte generiche come la seguente:

Come correggere le violazioni

Per correggere una violazione di questa regola, implementare una delle seguenti interfacce di raccolte generiche:

Esclusione di avvisi

L'esclusione di un avviso da questa regola è sicura; la raccolta, tuttavia, avrà un utilizzo più limitato.

Esempio di violazione

ms182132.collapse_all(it-it,VS.110).gifDescrizione

Nell'esempio seguente viene mostrata una classe (tipo di riferimento) che deriva dalla classe non generica CollectionBase che viola questa regola.

ms182132.collapse_all(it-it,VS.110).gifCodice

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

ms182132.collapse_all(it-it,VS.110).gifCommenti

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

ms182132.collapse_all(it-it,VS.110).gifDescrizione

Nell'esempio riportato di seguito viene corretta la violazione impostando la classe di base della raccolta impostata sulla classe non generica CollectionBase sulla classe generica Collection<T> (Collection(Of T) in Visual Basic).

ms182132.collapse_all(it-it,VS.110).gifCodice

using System;
using System.Collections.ObjectModel; 

namespace Samples
{    
    public class Book        
    {               
        public Book()                
        {                
        }        
    }    

    public class BookCollection : Collection<Book>    
    {        
        public BookCollection()        
        {        
        }    
    }
}

ms182132.collapse_all(it-it,VS.110).gifCommenti

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

ms182132.collapse_all(it-it,VS.110).gifDescrizione

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).

ms182132.collapse_all(it-it,VS.110).gifCodice

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

Vedere anche

Riferimenti

Generics (Guida per programmatori C#)