ОБНОВЛЕНИЕ : у меня было немного времени, так что ... я пошел дальше и развил эту идею. Ниже приведен код.
Вот немного сумасшедший ответ:
Вы могли бы делать то, что искали - по сути, обрабатывать двумерный массив как таблицу со строками - написав статический метод (возможно, метод расширения), который принимает T[,]
и возвращает IEnumerable<T[]>
. Однако для этого потребуется скопировать каждую «строку» базовой таблицы в новый массив.
Возможно, лучший (хотя и более сложный) подход заключается в написании класса, который реализует IList<T>
в качестве оболочки вокруг одной "строки" двумерного массива (вы, вероятно, установите IsReadOnly
в значение true и просто реализуйте метод получения для свойства this[int]
и, возможно, Count
и GetEnumerator
; все остальное может выдать NotSupportedException
). Тогда ваш метод static / extension может вернуть IEnumerable<IList<T>>
и обеспечить отложенное выполнение.
Таким образом, вы могли бы написать код, очень похожий на то, что у вас есть:
foreach (IList<string> row in table.GetRows()) // or something
{
Console.WriteLine(row[0] + " " + row[1]);
}
Просто мысль.
Предложение по реализации:
public static class ArrayTableHelper {
public static IEnumerable<IList<T>> GetRows<T>(this T[,] table) {
for (int i = 0; i < table.GetLength(0); ++i)
yield return new ArrayTableRow<T>(table, i);
}
private class ArrayTableRow<T> : IList<T> {
private readonly T[,] _table;
private readonly int _count;
private readonly int _rowIndex;
public ArrayTableRow(T[,] table, int rowIndex) {
if (table == null)
throw new ArgumentNullException("table");
if (rowIndex < 0 || rowIndex >= table.GetLength(0))
throw new ArgumentOutOfRangeException("rowIndex");
_table = table;
_count = _table.GetLength(1);
_rowIndex = rowIndex;
}
// I didn't implement the setter below,
// but you easily COULD (and then set IsReadOnly to false?)
public T this[int index] {
get { return _table[_rowIndex, index]; }
set { throw new NotImplementedException(); }
}
public int Count {
get { return _count; }
}
bool ICollection<T>.IsReadOnly {
get { return true; }
}
public IEnumerator<T> GetEnumerator() {
for (int i = 0; i < _count; ++i)
yield return this[i];
}
// omitted remaining IList<T> members for brevity;
// you actually could implement IndexOf, Contains, etc.
// quite easily, though
}
}
... теперь я думаю, что я должен дать StackOverflow перерыв на остаток дня;)