在C#中转换数组

kaa*_*lus 6 c# arrays casting

在C#中,我正在使用大型值类型数组.我希望能够转换兼容值类型的数组,例如:

struct Color
{
    public byte R, G, B, A;
}

Color[] bitmap1 = ...;
uint[] bitmap2 = MagicCast(bitmap1);
Run Code Online (Sandbox Code Playgroud)

我希望bitmap2与bitmap1共享内存(它们具有相同的位表示).我不想复制.

有办法吗?

CSh*_*pie 4

您可以通过使用 Structlayouts 覆盖两个数组来实现此目的。虽然这里的许多答案都写了如何使颜色结构也具有 uint,但这是关于“数组”转换:

这是邪恶的。

public static class ColorExtension
{
    public static uint[] GetUInts(this Color[] colors)
    {
        if(colors == null) throw new ArgumentNullException("colors");
        Evil e = new Evil { Colors = colors};
        return e.UInts;
    }

    [StructLayout(LayoutKind.Explicit)]
    struct Evil
    {
        [FieldOffset(0)]
        public Color[] Colors;
        [FieldOffset(0)]
        public uint[] UInts;
    }
}
Run Code Online (Sandbox Code Playgroud)

这基本上有两个引用相同内存位置的数组。

所以如果你想从颜色数组中获取 uint 数组,你可以这样做:

Color[] colors =  ...

uint[] uints = colors.GetUInts();
Run Code Online (Sandbox Code Playgroud)

正如评论中提到的,您可能还需要显式声明 colorstruct,否则运行时可能会摸索导致一些“奇怪”uint 值的顺序......

[StructLayout(LayoutKind.Sequential)] // Or explicit, but i bellieve Sequential is enough.
struct Color
{
      public byte R;

      public byte G;

      public byte B;

      public byte A;
}
Run Code Online (Sandbox Code Playgroud)

但不要尝试调试它...... 这是邪恶的原因之一: