I was wondering if it's possible to use some sort of Array.Copy method in C# to copy elements of one array to and array of same size but different type.
I get a struct from a native c++ library that contains a pointer to Integer and a size element. These integer values represent enum Values from enum Foo
.
At the moment I'm using a for loop. Is there a better/safer approach?
Thanks!
Using Array.Copy
throws an ArrayTypeMismatchException
as shown below:
using System;
public class Program
{
public enum Foo
{
FOO_1,
FOO_2
}
public static void Main(string[] args)
{
int nCount = 1;
Foo[] fooArr = new Foo[nCount];
Int32[] RawData = new Int32[nCount];
RawData[0] = 100;
Array.Copy(RawData, fooArr, nCount);
}
}
For some reason, neither Array.Copy
nor Buffer.BlockCopy
is happy to copy from an int[]
to a Foo[]
, although Array.Copy
can go in the other direction perfectly happily.
It looks to me like your options are:
The kind of copy you showed in your original post, although I'd write it as:
for (int i = 0; i < RawData.Length; i++)
{
fooArr[i] = RawData[i];
}
.. that way you don't have a redundant variable outside the scope of the loop
A LINQ-like-but-not-LINQ approach using Array.ConvertAll
:
var fooArr = Array.ConvertAll(RawData, x => (Foo) x);
... this is more efficient than the LINQ approach as it can create an array of the correct size to start with.
If you don't need the execution-time type to actually be Foo[]
, you can just cast without any copying... because the CLR is happy to treat an int[]
as a Foo[]
:
Foo[] fooArr = (Foo[]) (object) RawData;
At that point, you have a single array object, which you're viewing as either an int[]
(via RawData
) or a Foo[]
(via fooArr
). Changes via either variable will be visible in the other variable. This is clearly very efficient, but could lead to problems elsewhere depending on how you use fooArr
. If you just use it in foreach
loops or via regular index accesses, it would be fine.
See more on this question at Stackoverflow