Интерфейс IEnumerable — это то, что на самом деле возвращает IEnumerator, и именно поэтому существует этот интерфейс.
При вызове блока foreach вызывается метод IEnumerable.GetEnumerator() для получения перечислителя.
Если вы хотите отслеживать каждый элемент, то, поскольку они являются типами объектов, на них будут ссылаться, поэтому у вас будет актуальная версия. В элементе вы можете реализовать управление версиями, о котором вы упомянули, вот так.
public class SomeItem
{
private string _Value;
private int _Version = 0;
private int _LastKnown = 0;
public SomeItem()
{
}
public SomeItem(string value)
{
this._Value = value
}
public string Value
{
get { return this._Value; }
set { if (this._Value != value) { this._Value = value; this._Version++; } }
}
public int Version
{
get { return this._Version; }
}
public bool HasChanged
{
get { return (this._Version != _LastKnown); }
}
// Reset change tracking.
public void Reset()
{
this._LastKnown = this._Version;
}
}
В другом месте вы можете использовать что-то подобное в своем цикле.
private List<SomeItem> _Items = new List<SomeItem>();
// Add an item.
_Items.Add(new SomeItem("ABC"));
// Add a changed item.
SomeItem itemN = new SomeItem("EFG");
itemN.Value = "XYZ";
_Items.Add(itemN);
foreach (SomeItem item in _Items)
{
if (item.HasChanged)
{
// Do stuff here.
//throw new Exception()
}
}
ОБНОВЛЕНО
В качестве альтернативы, если вы просто хотите узнать, какие элементы изменились, вы можете сделать что-то вроде этого.
SomeItem[] changedItems = _Items.Where(item => item.HasChanged);
Согласно предложению dlev, если вы просто хотите узнать, изменилось ли что-либо, просто используйте.
if (_Items.Any(item => item.HasChanged))
{
// An item has changed, do stuff.
}
person
Bernie White
schedule
14.09.2011
IEnumerable.GetEnumerator()
действительно есть. - person BoltClock   schedule 14.09.2011foreach
над массивом или строкой,IEnumerator
действительно является воображаемым - вместо этого компилятор создает циклfor
. - person Gabe   schedule 14.09.2011