CA1010: コレクションは、ジェネリック インターフェイスを実装しなければなりません
プロパティ | 値 |
---|---|
ルール ID | CA1010 |
Title | コレクションは、ジェネリック インターフェイスを実装しなければなりません |
[カテゴリ] | デザイン |
修正が中断ありか中断なしか | なし |
.NET 8 では既定で有効 | いいえ |
原因
型では System.Collections.IEnumerable インターフェイスを実装しますが、System.Collections.Generic.IEnumerable<T> インターフェイスは実装しません。また、包含アセンブリのターゲットが .NET になっています。 この規則では、System.Collections.IDictionary を実装する型を無視します。
既定では、この規則の対象は外部から参照できる型のみですが、これは構成可能です。 また、ジェネリック インターフェイスを実装することを求めるように、追加のインターフェイスを構成することもできます。
規則の説明
コレクションの操作性を拡充するために、ジェネリック コレクション インターフェイスの 1 つを実装します。 これにより、コレクションを使用して、次のようなジェネリック コレクション型を設定できます。
- System.Collections.Generic.List<T>
- System.Collections.Generic.Queue<T>
- System.Collections.Generic.Stack<T>
違反の修正方法
この規則違反を修正するには、次のジェネリック コレクション インターフェイスのいずれかを実装します。
- System.Collections.Generic.IEnumerable<T>
- System.Collections.Generic.ICollection<T>
- System.Collections.Generic.IList<T>
どのようなときに警告を抑制するか
この規則からの警告は抑制してもかまいません。ただし、コレクションの使用はさらに制限されます。
警告を抑制する
単一の違反を抑制するだけの場合は、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、規則をもう一度有効にします。
#pragma warning disable CA1010
// The code that's violating the rule is on this line.
#pragma warning restore CA1010
ファイル、フォルダー、またはプロジェクトの規則を無効にするには、構成ファイルでその重要度を none
に設定します。
[*.{cs,vb}]
dotnet_diagnostic.CA1010.severity = none
詳細については、「コード分析の警告を抑制する方法」を参照してください。
分析するコードを構成する
次のオプションを使用して、コードベースのどの部分に対してこの規則を実行するかを構成します。
これらのオプションを構成できる対象は、この規則だけ、それを適用するすべての規則、それを適用するこのカテゴリ (デザイン) のすべての規則のいずれかです。 詳細については、「コード品質規則の構成オプション」を参照してください。
特定の API サーフェイスを含める
ユーザー補助に基づいて、この規則を実行するコードベースの部分を構成できます。 たとえば、非パブリック API サーフェイスでのみ規則を実行するように指定するには、プロジェクトの .editorconfig ファイルに次のキーと値のペアを追加します。
dotnet_code_quality.CAXXXX.api_surface = private, internal
追加の必須ジェネリック インターフェイス
必須のジェネリック完全修飾インターフェイス (->
で区切られている) を使用して、インターフェイス名 (|
で区切られている) のリストを構成できます。
許可されるインターフェイスの形式:
- インターフェイスの名前のみ (包含する型または名前空間に関係なく、その名前が指定されたすべてのインターフェイスが含まれます)
- そのシンボルのドキュメント ID 形式の完全修飾名 (オプションで
T:
プレフィックスも使用可)。
次に例を示します。
オプションの値 | まとめ |
---|---|
dotnet_code_quality.CA1010.additional_required_generic_interfaces = ISomething->System.Collections.Generic.IEnumerable`1 |
名前空間に関係なく ISomething を実装するすべての型は、System.Collections.Generic.IEnumerable<T> を実装することも期待されます。 |
dotnet_code_quality.CA1010.additional_required_generic_interfaces = T:System.Collections.IDictionary->T:System.Collections.Generic.IDictionary`2 |
System.Collections.IDictionary を実装するすべての型は、System.Collections.Generic.IDictionary<TKey,TValue> を実装することも期待されます。 |
例
次の例は、非ジェネリック CollectionBase
クラスから派生され、この規則に違反するクラスを示しています。
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>
クラスなど) の両方を既に実装している型へと、基底クラスを変更します。
インターフェイスの実装による修正
次の例では、IEnumerable<T>、ICollection<T>、および IList<T> のジェネリック インターフェイスを実装することによって違反を修正します。
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 => (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()
{
}
}
}
基底クラスの変更による修正
次の例では、コレクションの基底クラスを、非ジェネリック CollectionBase
クラスからジェネリック Collection<T>
(Visual Basic の Collection(Of T)
) クラスに変更することによって違反を修正します。
public class Book
{
public Book()
{
}
}
public class BookCollection : Collection<Book>
{
public BookCollection()
{
}
}
既に解放されているクラスの基底クラスの変更は、既存のコンシューマーに対する重大な変更と見なされます。
関連規則
- CA1005: ジェネリック型でパラメーターを使用しすぎないでください
- CA1000: ジェネリック型の静的メンバーを宣言しません
- CA1002: ジェネリック リストを公開しません
- CA1003: 汎用イベント ハンドラーのインスタンスを使用します
関連項目
.NET