While @Dmitry's answer pretty much covers why the original attempt has failed and what you should do to rectify, nonetheless, depending on your requirements, you may also want to consider wrapping each item/index in the array into some referential type, that is able to change the original array items:
public class MultiDimensionArrayItemReference<T>
{
private readonly Array _array;
private readonly Int32[] _indices;
public MultiDimensionArrayItemReference(Array array, params Int32[] indices)
{
if (array == null)
throw new ArgumentNullException(paramName: nameof(array));
if (indices == null)
throw new ArgumentNullException(paramName: nameof(indices));
this._array = array;
this._indices = indices;
}
public IReadOnlyCollection<Int32> Indices
{
get
{
return this._indices.ToList().AsReadOnly();
}
}
public T Value
{
get
{
return (T)this._array.GetValue(this._indices);
}
set
{
this._array.SetValue(value, this._indices);
}
}
public override string ToString()
{
return $"[{String.Join(", ", this._indices)}]:{this.Value}";
}
}
public static class MultiDimensionArrayItemReferenceExtensions
{
// That's for the two-dimensional array, but with some effort it can be generalized to support any arrays.
public static IEnumerable<MultiDimensionArrayItemReference<T>> EnumerateReferenceElements<T>(this T[,] array)
{
if (array == null)
throw new ArgumentNullException(paramName: nameof(array));
// Assume zero-based
var rows = array.GetLength(0);
var columns = array.GetLength(1);
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < columns; col++)
{
yield return new MultiDimensionArrayItemReference<T>(
array,
row,
col);
}
}
}
}
...
private static void PrintArray<T>(T[,] array)
{
// Assume zero-based
var rows = array.GetLength(0);
var columns = array.GetLength(1);
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < columns; col++)
{
Console.Write("{0, 7}", array[row, col]);
}
Console.WriteLine();
}
}
...
var array = new [,]
{
{ "a1", "a2" },
{ "b1", "b2" }
};
PrintArray(array);
Console.WriteLine();
var elements = array
.EnumerateReferenceElements()
.ToList();
foreach (var elem in elements)
{
Console.WriteLine(elem);
}
elements.ForEach(
elem =>
elem.Value = elem.Value + "_n");
Console.WriteLine();
PrintArray(array);
It will result in the following output:
a1 a2
b1 b2
[0, 0]:a1
[0, 1]:a2
[1, 0]:b1
[1, 1]:b2
a1_n a2_n
b1_n b2_n
It is not very efficient due to the need to store each item's indices, but still a possibile solution for some rare cases.