Potrzebuję łatwego sposobu na iterowanie po wielu kolekcjach bez ich scalania, a ja nie mogłem znaleźć niczego wbudowanego w .NET, który wygląda tak, jak to robi. Wydaje się, że taka sytuacja powinna być dość powszechna. Nie chcę wymyślać koła. Czy coś jest wbudowane w coś takiego:Czy .NET ma wbudowany IEnumerable dla wielu kolekcji?
public class MultiCollectionEnumerable<T> : IEnumerable<T>
{
private MultiCollectionEnumerator<T> enumerator;
public MultiCollectionEnumerable(params IEnumerable<T>[] collections)
{
enumerator = new MultiCollectionEnumerator<T>(collections);
}
public IEnumerator<T> GetEnumerator()
{
enumerator.Reset();
return enumerator;
}
IEnumerator IEnumerable.GetEnumerator()
{
enumerator.Reset();
return enumerator;
}
private class MultiCollectionEnumerator<T> : IEnumerator<T>
{
private IEnumerable<T>[] collections;
private int currentIndex;
private IEnumerator<T> currentEnumerator;
public MultiCollectionEnumerator(IEnumerable<T>[] collections)
{
this.collections = collections;
this.currentIndex = -1;
}
public T Current
{
get
{
if (currentEnumerator != null)
return currentEnumerator.Current;
else
return default(T);
}
}
public void Dispose()
{
if (currentEnumerator != null)
currentEnumerator.Dispose();
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public bool MoveNext()
{
if (currentIndex >= collections.Length)
return false;
if (currentIndex < 0)
{
currentIndex = 0;
if (collections.Length > 0)
currentEnumerator = collections[0].GetEnumerator();
else
return false;
}
while (!currentEnumerator.MoveNext())
{
currentEnumerator.Dispose();
currentEnumerator = null;
currentIndex++;
if (currentIndex >= collections.Length)
return false;
currentEnumerator = collections[currentIndex].GetEnumerator();
}
return true;
}
public void Reset()
{
if (currentEnumerator != null)
{
currentEnumerator.Dispose();
currentEnumerator = null;
}
this.currentIndex = -1;
}
}
}
Mogę się mylić, ale nie sądzę, słowo kluczowe "var" jest dostępny w C# 2.0. –
@Dan Masz rację, nie ma słowa kluczowego var w C# 2.0. Byłoby krótsze, aby użyć parametru typu T mimo to. Łatwa naprawa. –
Nie jest dostępny w kompilatorze C# 2.0, ale można użyć VS 2008 lub 2010 w celu kierowania .NET 2.0 z kodem, który używa słowa kluczowego 'var', który zostanie rozwiązany do rzeczywistego typu podczas kompilacji, pozostawiając środowisko wykonawcze o wiele mądrzejsze. –