IEnumerable
を使用してコレクションを読み取ることはできますが、コレクションを変更することはできません。変更する場合は、代わりにフィルター処理されたインデックスの列挙を返します。
public IEnumerable<int> FilteredIndexes
{
get
{
if (UsePredicate) {
return ItemsList
.Select((item, i) => i)
.Where(i => SomeCondition(ItemsList[i]));
}
return ItemsList.Select((item, i) => i);
}
}
このインデクサーを宣言したと仮定します
public T this[int index]
{
get { return ItemsList[index]; }
set { ItemsList[index] = value; }
}
このようにコレクションを使用できるようになりました
GenClass<string> stringCollection = new GenClass<string>();
//TODO: Add items
stringCollection.SomeCondition = s => s.StartsWith("A");
stringCollection.UsePredicate = true;
foreach (int index in stringCollection.FilteredIndexes) {
stringCollection[index] = stringCollection[index] + " starts with 'A'";
}
アップデート
インデックスを公開したくない場合は、コレクション アイテムを表すアイテム アクセサーとして使用されるクラスを作成できます。
public class Item<T>
{
private List<T> _items;
private int _index;
public Item(List<T> items, int index)
{
_items = items;
_index = index;
}
public T Value
{
get { return _items[_index]; }
set { _items[_index] = value; }
}
}
コレクションで、このプロパティを宣言します
public IEnumerable<Item<T>> FilteredItems
{
get
{
if (UsePredicate) {
return ItemsList
.Select((item, i) => new Item<T>(ItemsList, i))
.Where(item => SomeCondition(item.Value));
}
return ItemsList.Select((item, i) => new Item<T>(ItemsList, i));
}
}
これで、このようなコレクションを使用できます
foreach (Item<string> item in stringCollection.FilteredItems) {
item.Value = item.Value + " starts with 'A'";
}
一般的な注意: プライベート プロパティを安全にフィールドに変換できます。プロパティは通常、フィールド値を公開するための中間手段として使用されます。