How do I wrap int [,] with something like ReadOnlyCollection?
I can't seem to do this:
private int[,] _table = new int[9, 9];
private ReadOnlyCollection<int[,]> _tableReadOnly = new ReadOnlyCollection<int[,]>(_table);
My idea is to have a property that allows the user to read the _table, but I don't want them to change it, so I thought I could use ReadOnlyCollection for this question.
source to share
ReadOnlyCollection is a one-dimensional collection. You can make ReadOnlyCollection<ReadOnlyCollection<int>>
or create your own 2D wrapper class, for example:
public class ReadOnlyMatrix<T> {
private T[,] _data;
public ReadOnlyMatrix(T[,] data) {
_data = data;
}
public T this[int x, int y] {
get {
return _data[x, y];
}
}
}
source to share
The problem is when you are trying to combine a 2D mutable structure with a read-only 1D structure. To do this, you need multiple nesting levels.
ReadOnlyCollection<ReadOnlyCollection<int>>
The downside to this approach is that it essentially forces you to have the entire table in memory twice. ReadOnlyCollection<T>
required List<T>
as the only constructor argument. This way you will end up copying each of your lines to a new one List<int>
.
Another way to achieve this is to use a property indexer to return the value directly without resolving the mutation.
public int this[int i, int j] {
get { return _table[i,j]; }
}
This allows consumers to read data without having to mutate it.
source to share
You can do something like:
public class ReadOnly2DArray<T>
{
T[,] _array;
public ReadOnly2DArray(T[,] arrayToWrap)
{
_array = arrayToWrap;
}
public T this[int x, int y]
{
get { return _array[x, y]; }
}
}
it is possible to add other methods of the Array class (Length property, GetLength method, ...) if you need them.
Then you would use it like:
int[,] a = new int[2, 2];
ReadOnly2DArray<int> wrapper = new ReadOnly2DArray<int>(a);
int value = wrapper[0, 0]; // Can read values
//wrapper[0, 0] = value; // Won't compile
source to share