Condividi tramite


Gli insiemi devono implementare un'interfaccia generica

Aggiornamento: novembre 2007

TypeName

CollectionsShouldImplementGenericInterface

CheckId

CA1010

Categoria

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 un insieme, implementare una delle interfacce di insiemi generici. L'insieme potrà poi essere utilizzato per inserire dati in tipi di insiemi generici come il seguente:

Correzione delle violazioni

Per correggere una violazione di questa regola, implementare una delle seguenti interfacce di insiemi generici:

Esclusione di avvisi

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

Esempio di violazione

Descrizione

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

Codice

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

Commenti

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

Descrizione

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

Codice

using System;
using System.Collections.ObjectModel; 

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

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

Commenti

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

Descrizione

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

Codice

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

Evitare un uso eccessivo di parametri nei tipi generici

Non dichiarare membri statici su tipi generici

Non esporre elenchi generici

Non nidificare tipi generici nelle firme dei membri

I metodi generici devono fornire parametri di tipo

Utilizzare istanze di gestori eventi generici

Utilizzare generics quando opportuno

Vedere anche

Riferimenti

Generics (Guida per programmatori C#)