特定の条件が満たされた場合にのみ追加する Add メソッドを使用して List から派生したカスタム クラスがあります。
また、AddRange をオーバーライド*する必要がありますか?それとも、AddRange は指定された範囲の各要素に対して Add を呼び出すだけですか?
*: はい、C# のコンテキストで非表示になり、オーバーライドされませnew
ん。
カスタム コレクションを作成する場合。orから派生させたり、 orList<T>
からCollection<T>
直接実装しIList<T>
たりしないでくださいICollection<T>
。実際、クラスのAdd
メソッドList<T>
は仮想ではありません。
注:List<T>.AddRange
を使用しArray.Copy
ます。
Collection を継承するときは、2 つのメソッドをオーバーライドするだけです!
public class MyCollection : Collection<string>
{
private bool IsValidItem(string item)
{
return; // Your condition : true if valid; false, otherwise.
}
// This method will be called when you call MyCollection.Add or MyCollection.Insert
protected override void InsertItem(int index, string item)
{
if(IsValidItem(item))
base.InsertItem(index, item);
}
// This method will be called when you call MyCollection[index] = newItem
protected override void SetItem(int index, string item)
{
if(IsValidItem(item))
base.SetItem(index, item);
}
}
検証するアイテムが上記のコードで正しいタイプにstring
置き換えられていない場合。string
メソッドのセマンティクスを変更する隠蔽を使用しないでください。それは本当に悪い設計です。
を実装する新しいクラスを作成しますIList<T>
。これを行う最も簡単な方法は、から継承することですCollection<T>
。Collection<T>
実装し、メソッドIList<T>
の形式で 4 つの拡張ポイントがあります。protected virtual
InsertItem
SetItem
RemoveItem
ClearItems
削除されるアイテムではなく、追加されるアイテムのみを検証する必要があるため、オーバーライドする必要があるのはInsertItem
とSetItem
.
class MyCollection:Collection<T>
{
private void ValidateItem(T item)
{
if(item is invalid)
throw new ArgumentException("Item is invalid");
}
protected override InsertItem(int index, T item)
{
ValidateItem(item);
base.InsertItem(index, item);
}
protected override SetItem(int index, T item)
{
ValidateItem(item);
base.SetItem(index, item);
}
}
List<T>
有効なオブジェクトのみを追加することを除いて、とまったく同じように動作するコレクションが必要な場合は、カスタムコレクションを作成しません。
代わりに拡張機能を使用し、拡張機能が何をしているのかが明確である限り、拡張機能や好きなものをAddIfValid(T value)
呼び出します。AddRangeIfValid(IEnumerable<T>)
次に例を示します。
public static void AddIfValid(this List<T> list, T value)
{
if (/* check if value is valid here */)
list.Add(value);
}
拡張機能を定義したら、次のように使用します。
myList.AddIfValid(myValue);