てくメモ

trivial な notes

【C#】byte配列からの型変換

既存のバイナリファイルからの読取りをBinaryReaderクラスとシフト演算の組み合わせで行っているコードを見たのをきっかけに整理。


最初に、エンディアンの違いを実質考えなくてよいとき。

まず普通なのは、BitConverterクラスを使うこと。
これは特筆なし。


別の選択肢として、UnsafeクラスやMemoryMarshalクラスがある。

// ReadOnlySpan<byte> span;

// byte span -> T
int i = Unsafe.As<byte, int>(ref MemoryMarshal.GetReference(span));
// byte span -> span T
ReadOnlySpan<int> si = MemoryMarshal.Cast<byte, int>(span);

この場合の型は、構造体であればプリミティブ型でなくてもよい。
ただし、レイアウトは指定する。

// 例えばこういうのを定義
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public readonly record struct ByteOffset(
    byte X,
    byte Y);


次に、エンディアンの違いを考えるとき。

この場合、 BinaryPrimitivesクラスでエンディアン固定の読取りを(書込みも)行うメソッドが提供されている。


記事冒頭のように既存のバイナリファイルから読み取るような場合、ほとんどの場合は自前で頑張らずエンディアンを意識しないで扱っていい気はする。(当然要件にはよる)