It's possible to write a generic method that can convert arrays of any compatible type (by "compatible" I mean "elements must be value types and the size of the elements must be compatible").
You can use P/Invoke to call the Windows API CopyMemory() method.
However, bear in mind that there may not be any performance advantage to doing it this way; you should perform careful timings to be sure.
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
public TOut[] ConvertArray<TIn, TOut>(TIn[] input) where TIn:struct where TOut:struct
{
if (input == null)
throw new ArgumentNullException("input");
int sizeTIn = Marshal.SizeOf(typeof(TIn));
int sizeTOut = Marshal.SizeOf(typeof(TOut));
int sizeBytes = input.Length*sizeTIn;
if ((sizeBytes % sizeTOut) != 0)
throw new ArgumentException("Size of input type is not compatible with size of output type.");
int sizeOut = sizeBytes/sizeTOut;
var output = new TOut[sizeOut];
GCHandle inHandle = GCHandle.Alloc(input, GCHandleType.Pinned);
GCHandle outHandle = GCHandle.Alloc(output, GCHandleType.Pinned);
try
{
IntPtr inPtr = inHandle.AddrOfPinnedObject();
IntPtr outPtr = outHandle.AddrOfPinnedObject();
CopyMemory(outPtr, inPtr, (uint)sizeBytes);
}
finally
{
outHandle.Free();
inHandle.Free();
}
return output;
}
For your example, you could call this like so:
Demo[] test = new Demo[10];
for (int i = 0; i < 10; ++i)
test[i] = new Demo {X = i, Y = i};
var result = ConvertArray<Demo, double>(test);
for (int i = 0; i < 20; ++i)
Console.WriteLine(result[i]);