(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