如何创建多维ImmutableArray?是否存在更优实现方案?
处理.NET中不可变多维数组的更优方案
微软官方的ImmutableArray仅支持一维数组,你当前用ImmutableArray<T[,]>包装整个多维数组的方式虽然可行,但存在修改时需复制整个多维数组、性能开销大的问题。以下是几种更优的实现方式:
1. 自定义不可变二维数组类型
最贴近原生多维数组体验的方案,通过封装只读多维数组实现不可变性,修改操作返回新实例:
public class Immutable2DArray<T> { private readonly T[,] _array; public Immutable2DArray(int rows, int cols) { _array = new T[rows, cols]; } private Immutable2DArray(T[,] array) { _array = array; } public T this[int row, int col] => _array[row, col]; public int Rows => _array.GetLength(0); public int Columns => _array.GetLength(1); // 修改指定位置的值,返回新的不可变数组 public Immutable2DArray<T> Set(int row, int col, T value) { var newArray = (T[,])_array.Clone(); newArray[row, col] = value; return new Immutable2DArray<T>(newArray); } } // 使用示例 var immutable2D = new Immutable2DArray<int>(3, 3); immutable2D = immutable2D.Set(0, 0, 1); int val = immutable2D[0, 0]; // 1
2. 使用嵌套的ImmutableArray
用ImmutableArray<ImmutableArray<T>>模拟二维数组,符合Immutable集合的设计理念,修改某一行时仅需替换对应的子数组:
// 创建初始二维不可变数组 var rows = ImmutableArray.Create( ImmutableArray.Create(1, 2, 3), ImmutableArray.Create(4, 5, 6), ImmutableArray.Create(7, 8, 9) ); // 获取值 int value = rows[i][j]; // 修改指定位置的值:先复制目标行并修改,再替换原数组中的该行 var updatedRow = rows[i].SetItem(j, newValue); var updatedRows = rows.SetItem(i, updatedRow);
这种方式的优势是修改时无需复制整个二维结构,仅复制修改的行,性能更优,且支持LINQ操作。
3. 用ImmutableDictionary模拟稀疏多维数组
如果你的多维数组是稀疏的(大部分位置为空值),用ImmutableDictionary<(int Row, int Col), T>存储有效数据更节省空间:
var sparseImmutable = ImmutableDictionary<(int, int), int>.Empty .Add((0, 0), 1) .Add((2, 2), 9); // 获取值 if (sparseImmutable.TryGetValue((i, j), out int val)) { // 处理值 } // 修改值 sparseImmutable = sparseImmutable.SetItem((i, j), newValue);
方案对比
- 自定义不可变类型:性能最优,体验最接近原生多维数组,适合密集型、固定维度的场景。
- 嵌套
ImmutableArray:灵活性高,支持LINQ,适合需要频繁操作行数据的场景。 ImmutableDictionary:空间效率高,适合稀疏多维数据场景。
内容的提问来源于stack exchange,提问作者DavidY
相关产品推荐
相关产品推荐

