HOWTO · Csharp

C# でバイト配列を初期化する方法

C# で特定の長さのバイト配列を作成し、その値を設定し、生バイトをコピーする方法を学びます。

このページの内容

C# の byte[] は 0 から 255 までのバイト値を格納します。要素が初期状態でゼロを含む配列を作成するには new byte[length] を使用し、値がすでに分かっている場合は配列初期化子を使用します。ループ、Array.Fill、LINQ は繰り返し値や計算された値を割り当てることができます。Buffer.BlockCopy は、すでに配列に格納されているバイトをコピーするためのものです。

固定長または明示的な値でバイト配列を作成する

固定サイズの byte[] を作成するには、その長さを new byte[length] に渡します。ランタイムは各要素をゼロに初期化します。値を事前に知っている場合は、代わりに初期化子に記述します。ループは、各値がそのインデックスや別の計算に依存する場合に便利です。

以下の宣言は、2 つの一般的な形式を並べて示しています。1 つ目は 4 つの位置を予約し、2 つ目は 3 つのバイト値を直接列挙します。次にループは各位置を順番に訪れ、そのインデックスに基づいた値を格納します。Length は位置の数を提供するため、要求するサイズを変更しても同じループの形を適応できます。最後の行は両方の配列を出力するので、各形式で生成された値を比較できます。

using System;

class Program
{
    static void Main()
    {
        byte[] values = new byte[4];
        byte[] explicitValues = { 0x10, 0x20, 0x30 };

        for (int i = 0; i < values.Length; i++)
        {
            values[i] = (byte)(i + 1);
        }

        Console.WriteLine(string.Join(", ", values));
        Console.WriteLine(string.Join(", ", explicitValues));
    }
}
1, 2, 3, 4
16, 32, 48

最初の配列では、ループは 1、2、3、4 を格納します。明示的な初期化子は、列挙された 16 進数のバイト値を含む別の配列を作成します。

すべての要素を同じ値に設定する

プロジェクトのターゲットフレームワークが Array.Fill を提供している場合は、それを使用します。これは、指定された配列のすべての要素に 1 つのバイト値を割り当てます。その API がプロジェクトで利用できない場合は、配列の Length に対する for ループで同じ割り当てができます。

using System;

class Program
{
    static void Main()
    {
        byte[] buffer = new byte[4];
        Array.Fill(buffer, (byte)255);
        Console.WriteLine(string.Join(", ", buffer));
    }
}
255, 255, 255, 255

キャストにより、値の型が明示されます。バイトは 0 から 255 までの値を保持できます。

LINQ で繰り返し値から配列を作成する

Enumerable.Repeat は、要求された回数だけ値を含むシーケンスを生成します。ToArray を呼び出すことで、そのシーケンスを byte[] として実体化します。この例では、両方のメソッドを提供する System.Linq をインポートしています。

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        byte value = 42;
        int length = 5;
        byte[] values = Enumerable.Repeat(value, length).ToArray();
        Console.WriteLine(string.Join(", ", values));
    }
}
42, 42, 42, 42, 42

この方法は、新しい配列全体に同じ値を含める場合に読みやすくなります。すでに更新する配列がある場合は Array.Fill を使用します。

Buffer.BlockCopy で生バイトをコピーする

Buffer.BlockCopy は、byte[] や int[] など、要素型がプリミティブ型である配列間で生バイトをコピーします。そのソースと宛先のオフセットおよび count は、配列要素ではなくバイト単位で測定されます。ソースと宛先の範囲に、要求されたコピーに十分な容量があることを確認してください。これは一般的な値を生成したり埋めたりするものではありません。その作業にはループまたは Array.Fill を使用します。

この例では、ソースのバイト配列から 4 バイトを、バイトオフセット 1 から始まる宛先配列にコピーします。

using System;

class Program
{
    static void Main()
    {
        byte[] source = { 10, 20, 30, 40 };
        byte[] destination = new byte[6];

        Buffer.BlockCopy(source, 0, destination, 1, source.Length);
        Console.WriteLine(string.Join(", ", destination));
    }
}
0, 10, 20, 30, 40, 0

より大きな数値配列からバイトをコピーする場合でも、コピー数とオフセットはバイトを使用します。たとえば、これは 2 つの int 値から最初の 4 バイトを 4 バイトの宛先にコピーします。

using System;

class Program
{
    static void Main()
    {
        int[] numbers = { 0x01020304, 0x05060708 };
        byte[] bytes = new byte[4];

        Buffer.BlockCopy(numbers, 0, bytes, 0, bytes.Length);
        Console.WriteLine(string.Join(", ", bytes));
    }
}

数値配列の例はプラットフォームに依存します。各 int 内のバイトの順序はプラットフォームの表現に依存します。提供された環境では、この例は 4, 3, 2, 1 を生成しました。その観察された順序はプラットフォームの整数バイト表現に固有のものであり、普遍的ではありません。byte[] からコピーすると、その要素がすでにバイトであるため、この解釈を回避できます。

初期化方法を選択する

ゼロで初期化された固定サイズの配列が必要な場合は new byte[length] を使用し、既知の値の短いリストには初期化子を使用します。位置によって計算される値にはループを、既存の配列に 1 つの値を割り当てるには Array.Fill を、LINQ で繰り返し値の配列を構築するには Enumerable.Repeat(...).ToArray() を使用します。データがすでに配列内の生バイトとして存在し、コピーする必要がある場合は Buffer.BlockCopy を選択します。