カタバミさんのプログラミングノート

日曜プログラマーがプログラミング関係のメモを記録するブログです。

C#のUnsafeクラス

MicrosoftはNuGetを通してUnsafeクラスを公開しています。これを利用することで/unsafeオプションを使用せずに変数をポインタとして扱うことができるようになります。バイト配列を構造体として参照するあるいはその逆も可能なため、素直にバイト配列として取得後にMarshal.PtrToStructure関数で構造体を作成するよりもメモリが節約可能だと思います。

追伸 GCの発生でエラーが発生するリスクがあるそうです。

Unsafeクラス
名前空間:System.Runtime.CompilerServices.Unsafe
アセンブリ:System.Runtime.CompilerServices.Unsafe.dll

詳細は以下を参照して下さい。

Unsafe Class (System.Runtime.CompilerServices) | Microsoft Docs

バイト配列の一部をuint型で操作するサンプルコード

using System;
using System.Linq;
using System.Runtime.CompilerServices;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            var buffer = new byte[10];
            ref var i0 = ref Unsafe.As<byte, uint>(ref buffer[0]);
            ref var i4 = ref Unsafe.As<byte, uint>(ref buffer[4]);

            ConsoleWriteLine(buffer);
            // bufferの内容:
            // {00, 00, 00, 00, 00, 00, 00, 00, 00, 00}

            i0 = 0x12345678;
            ConsoleWriteLine(buffer);
            // {78, 56, 34, 12, 00, 00, 00, 00, 00, 00}
            buffer[1] = 0x00;
            ConsoleWriteLine(buffer);
            // {78, 00, 34, 12, 00, 00, 00, 00, 00, 00}

            i4 = 0xffffffff;
            ConsoleWriteLine(buffer);
            // {78, 00, 34, 12, FF, FF, FF, FF, 00, 00}
        }

        static void ConsoleWriteLine(byte[] array)
        {
            Console.WriteLine("{"
                + string.Join<string>(", ", array.Select(x => x.ToString("X2")))
                + "}");
        }
    }
}