更新:2007 年 11 月
| TypeName | CollectionsShouldImplementGenericInterface | 
| CheckId | CA1010 | 
| 类别 | Microsoft.Design | 
| 是否重大更改 | 否 | 
原因
某个外部可见的类型实现 System.Collections.IEnumerable 接口,但不实现 System.Collections.Generic.IEnumerable<T> 接口,而包含程序集以 .NET Framework 2.0 为目标。此规则忽略实现 System.Collections.IDictionary 的类型。
规则说明
若要扩大集合的用途,应实现某个泛型集合接口。然后,可以使用该集合来填充泛型集合类型,例如:
如何修复冲突
若要修复与该规则的冲突,请实现下列泛型集合接口之一:
何时禁止显示警告
可以安全地禁止显示与该规则有关的警告;但是,集合在使用上将有更多的限制。
冲突的示例
说明
下面的示例演示一个从非泛型 CollectionBase 类派生的类(引用类型),它与此规则冲突。
代码
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);
        }
    }
}
注释
若要修复与此规则的冲突,应该实现泛型接口或将基类更改为已经实现泛型和非泛型接口的类型,例如 Collection<T> 类。
通过基类更改进行修复
说明
下面的示例通过将集合的基类从非泛型 CollectionBase 类更改为泛型 Collection<T>(Visual Basic 中的 Collection(Of T))类来修复冲突。
代码
using System;
using System.Collections.ObjectModel; 
namespace Samples
{    
    public class Book        
    {               
        public Book()                
        {                
        }        
    }    
    public class BookCollection : Collection<Book>    
    {        
        public BookCollection()        
        {        
        }    
    }
}
注释
更改已发布类的基类视为对现有使用者进行了重大更改。
通过接口实现进行修复
说明
下面的示例通过实现以下泛型接口来修复冲突:IEnumerable<T>、ICollection<T> 和 IList<T>(Visual Basic 中的 IEnumerable(Of T)、ICollection(Of T) 和 IList(Of T))。
代码
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()
            {
            }
        }
    }
}