In C you can point to particular row in array, because C array is just sequence of items. Two subsequent arrays are just sequence of items again and that is why it is possible to access sub-array in C. That is why, you cannot get the size in array in C just from array pointer.
In C#, there are two types of "multidimensional" arrays: Multidimensional arrays and Jagged Arrays.
Classic multi-dimensional cannot be access just by sub-index because array in C# is not just a sequence of items, but there is also a header in which contain size of array, type pointer and sync block. Two subsequent C# arrays will contains a header inside and it will not fulfill C# array format.
Jagged array is array of arrays and you can access sub-array with only sub-index in similar way to C#.
Equivalent code in C# would be:
byte[][] palette = new byte[4][];
for (int i = 0; i < palette.Length; i++)
{
palette[i] = new byte[4];
}
byte[] destination = new byte[4];
int val = 1;
Array.Copy(palette[val & 3], 0, destination, 12, 4);
Be aware that in memcpy are parameters in order: destination, source whereas in Array.Copy are parameters in reverse order: source, destination