はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【C#】MemoryMarshal.Castを利用してある型の配列を他の型の配列に変換をする

はじめに

今回はMemoryMarshal.Castについて取り上げたいと思います。

learn.microsoft.com

// int[]からbyte[]に変換を行うサンプルコード

// 変換前:int[] (intは4バイト)
Span<int> from = Enumerable.Range(int.MaxValue - 5, 5).ToArray();

// 変換後:byte[] (intは4バイトなので、5*4=20バイト)
// Spanの指すメモリ領域は同じなので注意
Span<byte> to = MemoryMarshal.Cast<int, byte>(from);

// 250,255,255,127,251,255,255,127,252,255,255,127,253,255,255,127,254,255,255,127
foreach (var item in to) Console.WriteLine(item);

概要

MemoryMarshal.Castを用いることでプリミティブ型のSpanを別のプリミティブ型のSpanに変換してくれます。

public static ReadOnlySpan<TTo> Cast<TFrom,TTo> (ReadOnlySpan<TFrom> span) where TFrom : struct where TTo : struct;
public static Span<TTo> Cast<TFrom,TTo> (Span<TFrom> span) where TFrom : struct where TTo : struct;

1 つのプリミティブ型の読み取り専用スパンを、別のプリミティブ型の読み取り専用スパンにキャストします。

MemoryMarshal.Cast メソッド (System.Runtime.InteropServices) | Microsoft Learn

int[]ulong[]などの配列を、byte[]に変換したいときとかに使えますね。

使い方

// int[]からbyte[]に変換を行うサンプルコード

// 変換前:int[] (intは4バイト)
Span<int> from = Enumerable.Range(int.MaxValue - 5, 5).ToArray();

// 変換後:byte[] (intは4バイトなので、5*4=20バイト)
// Spanの指すメモリ領域は同じなので注意
Span<byte> to = MemoryMarshal.Cast<int, byte>(from);

// 250,255,255,127,251,255,255,127,252,255,255,127,253,255,255,127,254,255,255,127
foreach (var item in to) Console.WriteLine(item);

注意点

このメソッドは、メモリ アクセスの不整合をサポートしているプラットフォーム、またはメモリ ブロックが他の方法でアラインされている場合にのみサポートされます。

MemoryMarshal.Cast メソッド (System.Runtime.InteropServices) | Microsoft Learn

私自身ちゃんと理解できているか怪しいですが、端末によって不具合が出る可能性あり?