Нет, вы не можете этого сделать. Вы не можете перегрузить ваш итератор по умолчанию.
Представьте, можете ли вы перегрузить итератор по умолчанию.
Что бы это сделать? foreach (object o in foo)
, не было бы логичного способа выбрать правильный итератор.
Что вы можете сделать, так это иметь второй метод ForEach2, который выполняет итерацию по вашей коллекции другим способом. Или вы могли бы явно реализовать интерфейс. Или вы могли бы использовать композицию Linq для такого рода вещей.
С точки зрения дизайна класса:
interface IBar {
IEnumerator<string> GetEnumerator();
}
class Foo : IBar, IEnumerable<int> {
// Very bad, risky code. Enumerator implementations, should
// line up in your class design.
public IEnumerator<int> GetEnumerator()
{
yield return 1;
yield return 2;
yield return 3;
yield return 4;
}
IEnumerator<string> IBar.GetEnumerator()
{
yield return "hello";
}
// must be IEnumerable if you want to support foreach
public IEnumerable<string> AnotherIterator
{
get {
yield return "hello2";
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
Расширения LINQ для EachPair
struct Pair<T> {
public T First;
public T Second;
}
static class LinqExtension {
public static IEnumerable<Pair<T>> EachPair<T>(this IEnumerable<T> input) {
T first = default(T);
bool gotFirst = false;
foreach (var item in input)
{
if (!gotFirst)
{
first = item;
gotFirst = true;
}
else {
yield return new Pair<T>() { First = first, Second = item };
gotFirst = false;
}
}
}
}
Тестовый код:
class Program
{
static void Main(string[] args)
{
var foo = new Foo();
foreach (int number in foo)
{
Console.WriteLine(number);
}
// LINQ composition - a good trick where you want
// another way to iterate through the same data
foreach (var pair in foo.EachPair())
{
Console.WriteLine("got pair {0} {1}", pair.First, pair.Second);
}
// This is a bad and dangerous practice.
// All default enumerators should be the same, otherwise
// people will get confused.
foreach (string str in (IBar)foo)
{
Console.WriteLine(str);
}
// Another possible way, which can be used to iterate through
// a portion of your collection eg. Dictionary.Keys
foreach (string str in foo.AnotherIterator)
{
Console.WriteLine(str);
}
}