- 汎用ジェネリックコレクション ページ一覧
Collection
System.Collections.ObjectModel.Collectionクラスはジェネリックコレクションの基本クラスとして使えるクラスです。 並べ替えや述語を指定した検索の操作が用意されていない以外は、Listクラスとほぼ同じ操作が出来ます。
using System;
using System.Collections.ObjectModel;
class Sample {
static void Main()
{
Collection<int> col = new Collection<int>();
// 要素の追加
col.Add(0);
col.Add(1);
col.Add(2);
col.Add(3);
col.Add(4);
Print(col);
// 要素の削除
col.Remove(1);
col.Remove(3);
Print(col);
// 特定の位置にある要素を削除
col.RemoveAt(1);
Print(col);
// 特定の位置にある要素を変更
col[0] = 5;
Print(col);
// 特定の位置に要素を挿入
col.Insert(1, 6);
Print(col);
// 値4の要素が含まれているか
Console.WriteLine("Contains 4: {0}", col.Contains(4));
}
static void Print(Collection<int> col)
{
foreach (int e in col) {
Console.Write("{0}, ", e);
}
Console.WriteLine();
}
}
Imports System
Imports System.Collections.ObjectModel
Class Sample
Shared Sub Main()
Dim col As New Collection(Of Integer)
' 要素の追加
col.Add(0)
col.Add(1)
col.Add(2)
col.Add(3)
col.Add(4)
Print(col)
' 要素の削除
col.Remove(1)
col.Remove(3)
Print(col)
' 特定の位置にある要素を削除
col.RemoveAt(1)
Print(col)
' 特定の位置にある要素を変更
col(0) = 5
Print(col)
' 特定の位置に要素を挿入
col.Insert(1, 3)
Print(col)
' 値4の要素が含まれているか
Console.WriteLine("Contains 4: {0}", col.Contains(4))
End Sub
Shared Sub Print(ByVal col As Collection(Of Integer))
For Each e As Integer In col
Console.Write("{0}, ", e)
Next
Console.WriteLine()
End Sub
End Class
0, 1, 2, 3, 4, 0, 2, 4, 0, 4, 5, 4, 5, 6, 4, Contains 4: True
派生クラスから内部コレクションのIList<T>にアクセスするにはItemsプロパティを参照します。 また、次のプロテクトメソッドをオーバーライドすることで、要素の挿入・削除・設定時の動作を拡張出来ます。
メソッド | メソッドが呼ばれるタイミング |
---|---|
SetItem | 内部コレクションの要素を設定しようとしたとき |
InsertItem | 内部コレクションに要素を挿入しようとしたとき |
RemoveItem | 内部コレクションから要素を削除しようとしたとき |
ClearItems | 内部コレクションから全要素を削除しようとしたとき |
以下は、Collectionをクラスを継承して0または正の整数のみを格納できるコレクション型を実装する例です。
using System;
using System.Collections.ObjectModel;
class PositiveNumberCollection : Collection<int> {
protected override void SetItem(int index, int item)
{
// 要素が設定される際に値をチェックする
CheckRange(item);
base.SetItem(index, item);
}
protected override void InsertItem(int index, int item)
{
// 要素が設定される際に値をチェックする
CheckRange(item);
base.InsertItem(index, item);
}
private void CheckRange(int item)
{
// 値が負の場合はArgumentOutOfRangeExceptionをスローする
if (item < 0) throw new ArgumentOutOfRangeException("値が負数");
}
public void Sort()
{
// IListインターフェイスからArrayListのラッパーを作り、既定のIComparer<int>を使ってソートする
System.Collections.ArrayList.Adapter(this).Sort(System.Collections.Generic.Comparer<int>.Default);
}
public void Reverse()
{
// IListインターフェイスからArrayListのラッパーを作りリバースする
System.Collections.ArrayList.Adapter(this).Reverse();
}
}
class Sample {
static void Main()
{
PositiveNumberCollection col = new PositiveNumberCollection();
// 要素の追加
col.Add(3);
col.Add(1);
col.Add(0);
col.Add(2);
col.Add(4);
col[2] = 5;
try {
Console.WriteLine("Add(-1)");
col.Add(-1);
}
catch (ArgumentOutOfRangeException ex) {
Console.WriteLine(ex.Message);
}
Print(col);
// ソート
col.Sort();
Print(col);
// リバース
col.Reverse();
Print(col);
}
static void Print(PositiveNumberCollection col)
{
foreach (int e in col) {
Console.Write("{0}, ", e);
}
Console.WriteLine();
}
}
Imports System
Imports System.Collections.ObjectModel
Class PositiveNumberCollection
Inherits Collection(Of Integer)
Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As Integer)
' 要素が設定される際に値をチェックする
CheckRange(item)
MyBase.SetItem(index, item)
End Sub
Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As Integer)
' 要素が設定される際に値をチェックする
CheckRange(item)
MyBase.InsertItem(index, item)
End Sub
Private Sub CheckRange(ByVal item As Integer)
' 値が負の場合はArgumentOutOfRangeExceptionをスローする
If item < 0 Then Throw New ArgumentOutOfRangeException("値が負数")
End Sub
Public Sub Sort()
' IListインターフェイスからArrayListのラッパーを作り、既定のIComparer<int>を使ってソートする
System.Collections.ArrayList.Adapter(Me).Sort(System.Collections.Generic.Comparer(Of Integer).Default)
End Sub
Public Sub Reverse()
' IListインターフェイスからArrayListのラッパーを作りリバースする
System.Collections.ArrayList.Adapter(Me).Reverse()
End Sub
End Class
Class Sample
Shared Sub Main()
Dim col As New PositiveNumberCollection()
' 要素の追加
col.Add(3)
col.Add(1)
col.Add(0)
col.Add(2)
col.Add(4)
col(2) = 5
Try
Console.WriteLine("Add(-1)")
col.Add(-1)
Catch ex As ArgumentOutOfRangeException
Console.WriteLine(ex.Message)
End Try
Print(col)
' ソート
col.Sort()
Print(col)
' リバース
col.Reverse()
Print(col)
End Sub
Shared Sub Print(ByVal col As PositiveNumberCollection)
For Each e As Integer In col
Console.Write("{0}, ", e)
Next
Console.WriteLine()
End Sub
End Class
Add(-1) 指定された引数は、有効な値の範囲内にありません。 パラメーター名: 値が負数 3, 1, 5, 2, 4, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1,
ReadOnlyCollection
System.Collections.ObjectModel.ReadOnlyCollectionクラスは読み取り専用のジェネリックコレクションを作成するためのクラスです。
ReadOnlyCollectionクラスはArray.AsReadOnlyメソッドやList.AsReadOnlyメソッドの戻り値として返され、配列・Listを読み取り専用にしたコレクションとして取得することができます。 また、ReadOnlyCollectionクラスのインスタンスを作成する場合は基になるIList<T>をコンストラクタで指定する必要があり、この場合は指定されたIList<T>に対する読み取り操作のみを許可するラッパーとして動作します。
読み取り操作のみを許可するため、Add, Remove, Clearなどのパブリックメソッドのほか、SetItem, RemoveItem, InsertItemなどのプロテクトメソッドも提供されません。 また、基になるIList<T>に変更を加えるとそれをラップするReadOnlyCollectionにも反映されます。 ReadOnlyCollectionをIListインターフェイスなどにキャストしてAdd, Removeなどのメソッドを呼び出した場合は例外NotSupportedExceptionがスローされます。
派生クラスからは、Itemsプロパティを参照することで基になったIList<T>にアクセスすることが出来ます。
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
class Sample {
static void Main()
{
List<string> baseList = new List<string>(new string[] {"Alice", "Bob", "Charlie", "Dave", "Eve"});
ReadOnlyCollection<string> col = new ReadOnlyCollection<string>(baseList);
Print(col);
try {
// ReadOnlyCollection<string>からIList<string>にキャスト
IList<string> list = col;
// IList<string>インターフェイスのRemoveメソッドを呼び出す
Console.WriteLine("Remove 'Charlie'");
list.Remove("Charlie");
}
catch (NotSupportedException) {
Console.WriteLine("NotSupportedException");
}
// 基になっているコレクションに変更を加える
Console.WriteLine("Contains 'Charlie': {0}", col.Contains("Charlie"));
baseList.Remove("Charlie");
Print(col);
Console.WriteLine("Contains 'Charlie': {0}", col.Contains("Charlie"));
}
static void Print(ReadOnlyCollection<string> col)
{
foreach (string e in col) {
Console.Write("{0}, ", e);
}
Console.WriteLine();
}
}
Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Class Sample
Shared Sub Main()
Dim baseList As New List(Of String)(New String() {"Alice", "Bob", "Charlie", "Dave", "Eve"})
Dim col As New ReadOnlyCollection(Of String)(baseList)
Print(col)
Try
' ReadOnlyCollection(Of String)からIList(Of String)にキャスト
Dim list As IList(Of String) = col
' IList<string>インターフェイスのRemoveメソッドを呼び出す
Console.WriteLine("Remove 'Charlie'")
list.Remove("Charlie")
Catch ex As NotSupportedException
Console.WriteLine("NotSupportedException")
End Try
' 基になっているコレクションに変更を加える
Console.WriteLine("Contains 'Charlie': {0}", col.Contains("Charlie"))
baseList.Remove("Charlie")
Print(col)
Console.WriteLine("Contains 'Charlie': {0}", col.Contains("Charlie"))
End Sub
Shared Sub Print(ByVal col As ReadOnlyCollection(Of String))
For Each e As String In col
Console.Write("{0}, ", e)
Next
Console.WriteLine()
End Sub
End Class
Alice, Bob, Charlie, Dave, Eve, Remove 'Charlie' NotSupportedException Contains 'Charlie': True Alice, Bob, Dave, Eve, Contains 'Charlie': False