/// <summary>
/// Stellt Erweiterungsmethoden bereit.
/// </summary>
public static class Extensions
{
/// <summary>
/// Ruft einen speziellen Enumerator für ein zweidimensionales Array ab.
/// </summary>
/// <typeparam name="T">Der Typ der Elemente im Array.</typeparam>
/// <param name="source">Das Quellarray, dessen Enumerator abgerufen werden soll.</param>
/// <returns>Der Enumerator des Quellarrays.</returns>
public static IEnumerator<TwoDimensionalArrayEnumeratorItem<T>> ToTwoDimensionalArrayEnumerator<T>(this T[,] source)
{
return new TwoDimensionalArrayEnumerator<T>(source);
}
/// <summary>
/// Ruft einen Container für ein zweidimensionales Array ab, welcher einen speziellen Enumerator generieren kann.
/// </summary>
/// <typeparam name="T">Der Typ der Elemente im Array.</typeparam>
/// <param name="source">Das Quellarray, das in einen Container gepackt werden soll.</param>
/// <returns>Ein Container, welcher das Quellarray enthält.</returns>
public static TwoDimensionalEnumeratorArrayContainer<T> ToTwoDimensionalArrayEnumeratorContainer<T>(this T[,] source)
{
return new TwoDimensionalEnumeratorArrayContainer<T>(source);
}
}
/// <summary>
/// Stellt ein Element eines zweidimensionalen Arrays dar.
/// </summary>
/// <typeparam name="T">Der Typ des Elements.</typeparam>
public struct TwoDimensionalArrayEnumeratorItem<T>
{
/// <summary>
/// Initialisiert eine neue Instanz der <see cref="TwoDimensionalArrayEnumeratorItem{T}"/>-Klasse.
/// </summary>
/// <param name="x">Der Index der Spalte des Elements im Array.</param>
/// <param name="y">Die Index der Zeile des Elements im Array.</param>
/// <param name="item">Das Element des Arrays.</param>
internal TwoDimensionalArrayEnumeratorItem(int x, int y, T item)
: this()
{
this.X = x;
this.Y = y;
this.Item = item;
}
/// <summary>
/// Ruft den Index der Spalte des Elements im Array ab.
/// </summary>
public int X { get; private set; }
/// <summary>
/// Ruft den Index der Zeile des Elements im Array ab.
/// </summary>
public int Y { get; private set; }
/// <summary>
/// Ruft das Element ab.
/// </summary>
public T Item { get; private set; }
#region override
/// <summary>
/// Gibt eine Zeichenkette zurück, die das aktuelle Objekt darstellt. Nur für Debugzwecke.
/// </summary>
/// <returns>Eine Zeichenkette, die das aktuelle Objekt darstellt.</returns>
public override string ToString()
{
return string.Format("TwoDimensionalEnumeratorItem at x = {0} and y = {1}, Item = {2}", this.X, this.Y, this.Item);
}
/// <summary>
/// Ermittelt den Hashcode aus den Koordinaten des Elements und dem Element selbst.
/// </summary>
/// <returns>Der generierte Hashcode.</returns>
public override int GetHashCode()
{
return this.X ^ this.Y ^ this.Item.GetHashCode();
}
/// <summary>
/// Vergleicht ein Objekt mit dieser Instanz.
/// </summary>
/// <param name="obj">Das zu vergleichende Objekt.</param>
/// <returns><c>true</c>, wenn <paramref name="obj"/> mit dieser Instanz übereinstimmt; andernfalls <c>false</c>.</returns>
public override bool Equals(object obj)
{
if (!(obj is TwoDimensionalArrayEnumeratorItem<T>))
return false;
var item = (TwoDimensionalArrayEnumeratorItem<T>)obj;
return item.X == this.X && item.Y == this.Y && this.Item.Equals(this.Item);
}
#endregion
}
/// <summary>
/// Stellt eine Containerklasse, für ein Zweidimensionales Array, dar, welche einen speziellen Enumerator für das Array abrufen kann.
/// </summary>
/// <typeparam name="TItem">Der Typ der Elemente im Array.</typeparam>
public sealed class TwoDimensionalEnumeratorArrayContainer<TItem> : IEnumerable<TwoDimensionalArrayEnumeratorItem<TItem>>
{
TItem[,] source;
/// <summary>
/// Initialisiert eine neue Instanz der <see cref="TwoDimensionalEnumeratorArrayContainer{TItem}"/>-Klasse.
/// </summary>
/// <param name="source">Das Array, welches in den Container geladen werden soll.</param>
public TwoDimensionalEnumeratorArrayContainer(TItem[,] source)
{
this.source = source;
}
/// <summary>
/// Ruft den Enumerator für das Array ab.
/// </summary>
/// <returns></returns>
public IEnumerator<TwoDimensionalArrayEnumeratorItem<TItem>> GetEnumerator()
{
return this.source.ToTwoDimensionalArrayEnumerator();
}
#region IEnumerable<SpecialEnumeratorItem<T>> Member
IEnumerator<TwoDimensionalArrayEnumeratorItem<TItem>> IEnumerable<TwoDimensionalArrayEnumeratorItem<TItem>>.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
#region IEnumerable Member
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
#region override
/// <summary>
/// Gibt eine Zeichenkette zurück, die das aktuelle Objekt darstellt. Nur für Debugzwecke.
/// </summary>
/// <returns>Eine Zeichenkette, die das aktuelle Objekt darstellt.</returns>
public override string ToString()
{
return string.Format("TwoDimensionalEnumeratorContainer: {0}", source.ToString());
}
/// <summary>
/// Ruft den Hashcode des Quellarray ab.
/// </summary>
/// <returns>Der Hashcode des Quellarrays.</returns>
public override int GetHashCode()
{
return source.GetHashCode();
}
/// <summary>
/// Vergleicht ein Objekt mit dem Quellarray.
/// </summary>
/// <param name="obj">Das Objekt zum vergleichen.</param>
/// <returns><c>true</c>, wenn <paramref name="obj"/> mit dem Quellarray übereinstimmt; andernfalls <c>false</c></returns>
public override bool Equals(object obj)
{
return source.Equals(obj);
}
#endregion
}
/// <summary>
/// Stellt einen speziellen Enumerator für Zweidimensionale Arrays bereit.
/// </summary>
/// <typeparam name="TItem">Der Typ der Elemente, die der Enumerator zurück gibt.</typeparam>
public sealed class TwoDimensionalArrayEnumerator<TItem> : IEnumerator<TwoDimensionalArrayEnumeratorItem<TItem>>
{
TItem[,] source;
int mx, my;
int x = -1, y = 0;
TwoDimensionalArrayEnumeratorItem<TItem> current;
/// <summary>
/// Initialisiert eine neue Instanz der <see cref="TwoDimensionalArrayEnumerator{TItem}"/>-Klasse.
/// </summary>
/// <param name="source"></param>
public TwoDimensionalArrayEnumerator(TItem[,] source)
{
this.source = source;
this.mx = source.GetLength(0);
this.my = source.GetLength(1);
}
#region IEnumerator<SpecialEnumeratorItem<T>> Member
/// <summary>
/// Ruft das aktuell vom Enumerator ausgewählte Element ab.
/// </summary>
public TwoDimensionalArrayEnumeratorItem<TItem> Current
{
get
{
return this.current;
}
}
#endregion
#region IDisposable Member
void IDisposable.Dispose() { }
#endregion
#region IEnumerator Member
object IEnumerator.Current
{
get
{
return this.current;
}
}
/// <summary>
/// Setzt den Enumerator auf das nächste Element im Array.
/// </summary>
/// <returns><c>true</c>, wenn der Enumerator auf das nächste Element gesetzt werden konnte; andernfalls <c>false</c></returns>
public bool MoveNext()
{
if ((++this.x) >= mx)
{
if (++this.y >= my)
return false;
this.x = 0;
}
this.current = new TwoDimensionalArrayEnumeratorItem<TItem>(x, y, this.source[x, y]);
return true;
}
/// <summary>
/// Setzt den Enumerator auf seine Standardinitialisierung zurück.
/// </summary>
public void Reset()
{
this.x = -1;
this.y = 0;
}
#endregion
#region override
/// <summary>
/// Gibt eine Zeichenkette zurück, die das aktuelle Objekt darstellt. Nur für Debugzwecke.
/// </summary>
/// <returns>Eine Zeichenkette, die das aktuelle Objekt darstellt.</returns>
public override string ToString()
{
return string.Format("TwoDimensionalEnumerator array with {1} columns and {0} rows.", this.x, this.y);
}
#endregion
}