Строго говоря, я бы сказал, что если вы хотите сделать именно то, что говорите, то да, вам нужно будет вызвать GetEnumerator и самостоятельно управлять перечислителем с помощью цикла while.
Не зная слишкомЧто касается требований вашего бизнеса, вы можете воспользоваться функцией итератора, например, такой:
public static IEnumerable<decimal> IgnoreSmallValues(List<decimal> list)
{
decimal runningTotal = 0M;
foreach (decimal value in list)
{
// if the value is less than 1% of the running total, then ignore it
if (runningTotal == 0M || value >= 0.01M * runningTotal)
{
runningTotal += value;
yield return value;
}
}
}
Тогда вы можете сделать это:
List<decimal> payments = new List<decimal>() {
123.45M,
234.56M,
.01M,
345.67M,
1.23M,
456.78M
};
foreach (decimal largePayment in IgnoreSmallValues(payments))
{
// handle the large payments so that I can divert all the small payments to my own bank account. Mwahaha!
}
Обновлено:
Итак, вот продолжение того, что я назвал своим решением "рыболовный крючок".Теперь позвольте мне добавить заявление об отказе от ответственности, о котором я не могу придумать вескую причину сделать что-то таким образом, но ваша ситуация может отличаться.
Идея состоит в том, что вы просто создаете объект "рыболовный крючок" (ссылочный тип), который вы передаете своей функции итератора.Функция итератора манипулирует вашим объектом рыболовного крючка, и, поскольку у вас все еще есть ссылка на него во внешнем коде, вы можете видеть, что происходит:
public class FishingHook
{
public int Index { get; set; }
public decimal RunningTotal { get; set; }
public Func<decimal, bool> Criteria { get; set; }
}
public static IEnumerable<decimal> FishingHookIteration(IEnumerable<decimal> list, FishingHook hook)
{
hook.Index = 0;
hook.RunningTotal = 0;
foreach(decimal value in list)
{
// the hook object may define a Criteria delegate that
// determines whether to skip the current value
if (hook.Criteria == null || hook.Criteria(value))
{
hook.RunningTotal += value;
yield return value;
hook.Index++;
}
}
}
Вы можете использовать его следующим образом:
List<decimal> payments = new List<decimal>() {
123.45M,
.01M,
345.67M,
234.56M,
1.23M,
456.78M
};
FishingHook hook = new FishingHook();
decimal min = 0;
hook.Criteria = x => x > min; // exclude any values that are less than/equal to the defined minimum
foreach (decimal value in FishingHookIteration(payments, hook))
{
// update the minimum
if (value > min) min = value;
Console.WriteLine("Index: {0}, Value: {1}, Running Total: {2}", hook.Index, value, hook.RunningTotal);
}
// Resultint output is:
//Index: 0, Value: 123.45, Running Total: 123.45
//Index: 1, Value: 345.67, Running Total: 469.12
//Index: 2, Value: 456.78, Running Total: 925.90
// we've skipped the values .01, 234.56, and 1.23
По сути, объект FishingHook дает вам некоторый контроль над тем, как выполняется итератор.У меня сложилось впечатление, что у меня возник вопрос, что вам нужен какой-то способ доступа к внутренней работе итератора, чтобы вы могли манипулировать его итерацией, пока вы находитесь в середине итерации, но если это не так, то это решение можетбыть излишним за то, что вам нужно.