So you have samples with different number of bits per sample. To avoid using different types of output arrays, you can store the result in the largest supported width (here 64).
Untested example:
int bytes_per_sample = dataWidth / 8;
int num_samples = data.Length / bytes_per_sample;
UInt64[] samples = new UInt64[num_samples];
for (int i = 0; i < num_samples; i++)
{
samples[i] = data[i * bytes_per_sample];
for (int j = 1, uint shift = 8; j < bytes_per_sample; j++, shift += 8)
{
samples[i] |= data[i * bytes_per_sample + j] << shift;
}
}
Note that the above assumes the first bytes in the input stream are the lower bytes. If that does not apply, the above code has to be modified accordingly.