Как и где использовать перечислители
Перечислитель - это объект, который предоставляет возможность обхода контейнера или коллекции. Перечислители могут использоваться для чтения данных в коллекции, но они не могут использоваться для изменения основной коллекции, в то время как IEnumerable - это интерфейс, который определяет один метод GetEnumerator, который возвращает интерфейс IEnumerator, который, в свою очередь, позволяет только для чтения доступ к коллекции.
API Aspose.Cells предоставляет множество перечислителей, однако в данной статье обсуждаются в основном три типа, перечисленные ниже.
- Перечислитель ячеек
- Перечислитель строк
- Перечислитель столбцов
Как использовать перечислители
Перечислитель ячеек
Существуют различные способы доступа к перечислителю ячеек, и можно использовать любые из этих методов в зависимости от требований приложения. Вот методы, возвращающие перечислитель ячеек.
Все вышеперечисленные методы возвращают перечислитель, который позволяет осуществлять обход коллекции ячеек, которые были инициализированы.
Приведенный ниже пример кода демонстрирует реализацию интерфейса IEnumerator для коллекции Cells.
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET | |
// The path to the documents directory. | |
string dataDir = RunExamples.GetDataDir(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | |
// Load a file in an instance of Workbook | |
var book = new Workbook(dataDir + "sample.xlsx"); | |
// Get the enumerator from Cells collection | |
IEnumerator cellEnumerator = book.Worksheets[0].Cells.GetEnumerator(); | |
// Traverse cells in the collection | |
while (cellEnumerator.MoveNext()) | |
{ | |
var cell = cellEnumerator.Current as Aspose.Cells.Cell; | |
Console.WriteLine(cell.Name + " " + cell.Value); | |
} | |
// Get enumerator from an object of Row | |
IEnumerator rowEnumerator = book.Worksheets[0].Cells.Rows[0].GetEnumerator(); | |
// Traverse cells in the given row | |
while (rowEnumerator.MoveNext()) | |
{ | |
var cell = rowEnumerator.Current as Aspose.Cells.Cell; | |
Console.WriteLine(cell.Name + " " + cell.Value); | |
} | |
// Get enumerator from an object of Range | |
IEnumerator rangeEnumerator = book.Worksheets[0].Cells.CreateRange("A1:B10").GetEnumerator(); | |
// Traverse cells in the range | |
while (rangeEnumerator.MoveNext()) | |
{ | |
var cell = rangeEnumerator.Current as Aspose.Cells.Cell; | |
Console.WriteLine(cell.Name + " " + cell.Value); | |
} |
Перечислитель строк
Перечислитель строк можно получить при использовании метода RowCollection.GetEnumerator. Приведенный ниже пример кода демонстрирует реализацию интерфейса IEnumerator для RowCollection.
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET | |
// Load a file in an instance of Workbook | |
var book = new Workbook(dataDir + "sample.xlsx"); | |
// Get the enumerator for RowCollection | |
IEnumerator rowsEnumerator = book.Worksheets[0].Cells.Rows.GetEnumerator(); | |
// Traverse rows in the collection | |
while (rowsEnumerator.MoveNext()) | |
{ | |
var row = rowsEnumerator.Current as Aspose.Cells.Row; | |
Console.WriteLine(row.Index); | |
} |
Перечислитель столбцов
Перечислитель столбцов можно получить при использовании метода ColumnCollection.GetEnumerator. Приведенный ниже пример кода демонстрирует реализацию интерфейса IEnumerator для ColumnCollection.
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET | |
// Load a file in an instance of Workbook | |
var book = new Workbook(dataDir + "sample.xlsx"); | |
// Get the enumerator for ColumnsCollection | |
IEnumerator colsEnumerator = book.Worksheets[0].Cells.Columns.GetEnumerator(); | |
// Traverse columns in the collection | |
while (colsEnumerator.MoveNext()) | |
{ | |
var col = colsEnumerator.Current as Aspose.Cells.Column; | |
Console.WriteLine(col.Index); | |
} |
Где использовать перечислители
Чтобы обсудить преимущества использования перечислителей, давайте рассмотрим реальный пример.
Сценарий
Требование приложения состоит в том, чтобы обойти все ячейки в заданном Worksheet для чтения их значений. Существует несколько способов реализации этой цели. Некоторые из них показаны ниже.
Использование диапазона отображения
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET | |
// Load a file in an instance of Workbook | |
var book = new Workbook(dataDir + "sample.xlsx"); | |
// Get Cells collection of first worksheet | |
var cells = book.Worksheets[0].Cells; | |
// Get the MaxDisplayRange | |
var displayRange = cells.MaxDisplayRange; | |
// Loop over all cells in the MaxDisplayRange | |
for (int row = displayRange.FirstRow; row < displayRange.RowCount; row++) | |
{ | |
for (int col = displayRange.FirstColumn; col < displayRange.ColumnCount; col++) | |
{ | |
// Read the Cell value | |
Console.WriteLine(displayRange[row, col].StringValue); | |
} | |
} |
Использование MaxDataRow и MaxDataColumn
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET | |
// Load a file in an instance of Workbook | |
var book = new Workbook(dataDir + "sample.xlsx"); | |
// Get Cells collection of first worksheet | |
var cells2 = book.Worksheets[0].Cells; | |
int maxDataRow = cells2.MaxDataRow; | |
int maxDataColumn = cells2.MaxDataColumn; | |
// Loop over all cells | |
for (int row = 0; row <= maxDataRow; row++) | |
{ | |
for (int col = 0; col <= maxDataColumn; col++) | |
{ | |
// Read the Cell value | |
var currentCell = cells2.CheckCell(row, col); | |
if (currentCell != null) | |
{ | |
Console.WriteLine(currentCell.StringValue); | |
} | |
} | |
} |
Как видите, оба вышеупомянутых подхода используют более или менее похожую логику: цикл по всем ячейкам в коллекции для чтения значений ячеек. Это может вызвать проблемы по ряду причин, о которых рассказано ниже.
- API, такие как MaxRow, MaxDataRow, MaxColumn, MaxDataColumn и MaxDisplayRange, требуют дополнительного времени для сбора соответствующей статистики. В случае большой матрицы данных (строки x столбцы) использование этих API может отрицательно сказаться на производительности.
- В большинстве случаев не все ячейки в заданном диапазоне созданы. В таких ситуациях проверка каждой ячейки в матрице не так эффективна, как проверка только инициализированных ячеек.
- Доступ к ячейке в цикле в виде Cells row, column заставит создавать все объекты ячеек в диапазоне, что в конечном итоге может вызвать исключение OutOfMemoryException.
Заключение
Исходя из вышеуказанных фактов, возможны следующие сценарии использования перечислителей.
- Требуется только чтение коллекции ячеек, то есть только проверка ячеек.
- Необходимо пройти большое количество ячеек.
- Требуется пройти только инициализированные ячейки/строки/столбцы.