(See the last code sample in this answer for the best solution.)
You can actually use a Span<T> to do this, but it looks quite fiddly!
double[,,,] arrayToFill = new double[7, 8, 9, 10];
var data = MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, double>(ref MemoryMarshal.GetArrayDataReference(arrayToFill)),
arrayToFill.Length);
data.Fill(1.2345);
foreach (var value in arrayToFill)
{
Console.WriteLine(value); // All values are 1.2345
}
You can write a method to encapsulate this:
public static void FillArray<T>(Array array, T value)
{
var data = MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array)),
array.Length);
data.Fill(value);
}
Then the call site becomes a lot more readable:
double[,,,] arrayToFill = new double[7, 8, 9, 10];
FillArray(arrayToFill, 1.2345);
foreach (var value in arrayToFill)
{
Console.WriteLine(value); // All values are 1.2345
}
If you want to get more fancy you can encapsulate this in an extension method:
public static class ArrayExt
{
public static void Fill<T>(this Array array, T value)
{
var data = MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array)),
array.Length);
data.Fill(value);
}
}
Then you can call it like so:
double[,,,] arrayToFill = new double[7, 8, 9, 10];
arrayToFill.Fill(1.2345);
foreach (var value in arrayToFill)
{
Console.WriteLine(value); // All values are 1.2345
}
IMPORTANT! You must ensure that you use the correct type with which to fill the array. If you specify the wrong type it will fill the array with rubbish, for example:
arrayToFill.Fill(1);
will really mess things up.
In this example you'd need to do arrayToFill.Fill<double>(1); to specify the correct type because otherwise it will infer the wrong type for filling the array.
As per comments from /u/charlieface, you can circumvent this issue by adding strongly-typed overloads for each array dimension, thusly:
This is probably the best approach:
public static class ArrayExt
{
public static void Fill<T>(this T[,] array, T value) => fill(array, value);
public static void Fill<T>(this T[,,] array, T value) => fill(array, value);
public static void Fill<T>(this T[,,,] array, T value) => fill(array, value);
public static void Fill<T>(this T[,,,,] array, T value) => fill(array, value);
static void fill<T>(Array array, T value)
{
var data = MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array)),
array.Length);
data.Fill(value);
}
// ...etc etc. But does anyone really need more than a 5D array? ;)
}
Then arrayToFill.Fill(1); will work correctly.
Also see this post from /u/charlieface
Arraymethods work only on 1D arrays. The obvious option is to write your own extension method and then you can call that on any multidimensional array you want. You could overload it to handle various ranks with explicit loops or you could write a more complex method that could handle any rank.