删除元素会造成迭代器失效,这个一直是stl和c#的迭代器模式令人不大爽的地方。但如果需要一个删除安全的迭代器,该如何做呢?
造成迭代器失效的根本原因无法就是因为删除元素会破坏迭代器的状态机,只要在删除或添加时不破坏迭代器的状态机即可实现我们的需求。下面给出了一个简单的解决方案:
class Program
{
static void Main(string[] args)
{
SafeList<int> l = new SafeList<int>();
l.Add(1);
l.Add(2);
l.Add(3);
foreach (var item in l.ItemList)
{
if (item == 2)
l.Remove(item);
}
foreach (var item in l.ItemList)
{
Console.WriteLine(item);
}
}
}
class SafeItem<T>
{
public T Value { get; set; }
public bool IsRemoved { get; set; }
}
class SafeList<T>
{
List<SafeItem<T>> itemList = new List<SafeItem<T>>();
public void Add(T value)
{
itemList.Add(new SafeItem<T> { Value = value });
}
public bool Remove(T value)
{
var item = itemList.Find(i => i.Value.Equals(value));
if (item != null)
{
item.IsRemoved = true;
return true;
}
else
{
return false;
}
}
public IEnumerable<T> ItemList
{
get
{
itemList.RemoveAll(i => i.IsRemoved);
foreach (var item in itemList)
{
if (item.IsRemoved)
continue;
yield return item.Value;
}
}
}
}
上述代码比较简单,可能并不适合所有情况。读者可根据自己的需求相应改动。