既存のバイナリファイルからの読取りを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
クラスでエンディアン固定の読取りを(書込みも)行うメソッドが提供されている。
記事冒頭のように既存のバイナリファイルから読み取るような場合、ほとんどの場合は自前で頑張らずエンディアンを意識しないで扱っていい気はする。(当然要件にはよる)