如何在C#对象中实现无命名Get/Set方法,支持网格式索引存取?
StringGrid Class for Cell Access and Excel Export Alright, let's put together that StringGrid class you're looking for. I'll walk you through a complete implementation that covers all your requirements, plus some extra robustness to handle sparse rows/columns (like your example where column 2 is skipped).
Core Class Setup
We'll use a nested dictionary to store cell values—this is perfect for sparse grids because it only keeps track of cells you actually populate, no wasted space for empty rows/columns.
using System.Collections.Generic; using System.Linq; using ClosedXML.Excel; public class StringGrid { // Underlying storage: row number → column number → cell value private readonly Dictionary<int, Dictionary<int, string>> _gridData = new(); // Indexer for easy cell read/write (standard C# syntax uses [], not ()) public string this[int row, int col] { get { // Return empty string if the cell doesn't exist (no nulls!) if (_gridData.TryGetValue(row, out var rowCells) && rowCells.TryGetValue(col, out var value)) return value; return string.Empty; } set { // Create the row's cell dictionary if it doesn't exist yet if (!_gridData.ContainsKey(row)) _gridData[row] = new Dictionary<int, string>(); _gridData[row][col] = value; } }
Excel Export Functionality
Next, we'll add the ExportToExcel method that writes your grid to a ClosedXML Worksheet. It'll respect your starting row/column and handle sparse cells seamlessly.
public void ExportToExcel(IXLWorksheet targetWorksheet, int startRow = 1, int startCol = 1) { if (targetWorksheet == null) throw new ArgumentNullException(nameof(targetWorksheet), "Worksheet cannot be null"); // Loop through rows in order, then columns in order to maintain your grid structure foreach (var rowEntry in _gridData.OrderBy(r => r.Key)) { int excelRow = startRow + (rowEntry.Key - 1); foreach (var colEntry in rowEntry.Value.OrderBy(c => c.Key)) { int excelCol = startCol + (colEntry.Key - 1); targetWorksheet.Cell(excelRow, excelCol).Value = colEntry.Value; } } } }
Example Usage (Just Like Your Request)
Here's how you'd use the class exactly as you outlined—note that C# uses [] for indexer access (instead of () which is VB syntax, but this is the standard, idiomatic approach in C#):
// Initialize your grid StringGrid sg = new StringGrid(); // Populate cells, skipping column 2 as you intended sg[1, 1] = "Eastern Cities"; sg[2, 1] = "Boston"; sg[3, 1] = "New York"; sg[4, 1] = "Atlanta"; // Export to an Excel file using var workbook = new XLWorkbook(); var worksheet = workbook.Worksheets.Add("City List"); sg.ExportToExcel(worksheet); // Save the workbook to disk workbook.SaveAs("EasternCities.xlsx");
Quick Notes
- Sparse Grid Handling: The class doesn't care if you skip rows or columns—empty cells just return an empty string, and won't be written to Excel unless you modify the export method to fill them (easy to add if you need it later).
- ClosedXML Dependency: Don't forget to install the
ClosedXMLNuGet package in your project to use the Excel features. - Indexer Syntax: If you really need to use
()instead of[]for some reason, you could addGetCell(int row, int col)andSetCell(int row, int col, string value)methods, but indexers are the standard way to do this in C#.
内容的提问来源于stack exchange,提问作者Jason V

