Export (0) Print
Expand All
Expand Minimize

CA1010: Collections should implement generic interface

TypeName

CollectionsShouldImplementGenericInterface

CheckId

CA1010

Category

Microsoft.Design

Breaking Change

Non-breaking

An externally visible type implements the IEnumerable interface but does not implement the IEnumerable interface, and the containing assembly targets .NET Framework 2.0. This rule ignores types that implement IDictionary.

To broaden the usability of a collection, implement one of the generic collection interfaces. Then the collection can be used to populate generic collection types such as the following:

To fix a violation of this rule, implement one of the following generic collection interfaces:

It is safe to suppress a warning from this rule; however, the collection will have a more limited use.

The following example shows a class (reference type) that derives from the non-generic CollectionBase class, which violates this rule.

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

To fix a violation of this violation, you should either implement the generic interfaces or change the base class to a type that already implements both the generic and non-generic interfaces, such as the Collection<T> class.

The following example fixes the violation by changing the base class of the collection from the non-generic CollectionBase class to the generic Collection<T> (Collection(Of T) in Visual Basic) class.

using System;
using System.Collections.ObjectModel; 

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

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

Changing the base class of an already released class is considered a breaking change to existing consumers.

The following example fixes the violation by implementing these generic interfaces: IEnumerable<T>, ICollection<T>, and IList<T> (IEnumerable(Of T), ICollection(Of T), and IList(Of T) in Visual Basic).

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()
            {
            }
        }
    }
}
Show:
© 2015 Microsoft