CA1010:集合應該實作泛型介面
型別名稱 |
CollectionsShouldImplementGenericInterface |
CheckId |
CA1010 |
分類 |
Microsoft.Design |
中斷變更 |
中斷 |
原因
外部可見的型別會實作 IEnumerable 介面,但不會實作 IEnumerable 介面,而且包含組件 (Assembly) 會以 .NET Framework 2.0 為目標。這個規則會忽略實作 IDictionary 的型別。
規則描述
若要放寬集合的可用性,請實作其中一個泛型集合介面。然後,使用該集合填入 (Populate) 泛型集合型別 (例如下列項目):
如何修正違規
若要修正這個規則的違規情形,請實作下列其中一個泛型集合介面:
隱藏警告的時機
請放心地隱藏這個規則的警告,不過,該集合的使用將會更受限制。
範例違規
描述
下列範例顯示衍生自違反此規則的非泛型 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);
}
}
}
註解
若要修正這個規則的違規,應該實作泛型介面或將基底類別 (Base Class) 變更為已經實作泛型和非泛型介面 (例如 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()
{
}
}
}
}