固定サイズ バッファー (C# プログラミング ガイド)Fixed Size Buffers (C# Programming Guide)

C# では、fixed ステートメントを使って、データの構造体に固定サイズの配列を持ったバッファーを作成することができます。In C#, you can use the fixed statement to create a buffer with a fixed size array in a data structure. 固定サイズのバッファーは、他の言語またはプラットフォームのデータ ソースと相互運用するメソッドを作成するときに便利です。Fixed size buffers are useful when you write methods that interop with data sources from other languages or platforms. この固定配列には、標準的な構造体メンバーで許容されている属性または修飾子であれば、何でも適用することができます。The fixed array can take any attributes or modifiers that are allowed for regular struct members. ただし配列の型は boolbytecharshortintlongsbyteushortuintulongfloatdouble のいずれかに該当する必要があり、それが唯一の制限となります。The only restriction is that the array type must be bool, byte, char, short, int, long, sbyte, ushort, uint, ulong, float, or double.

private fixed char name[30];

RemarksRemarks

セーフ コードでは、配列を含む C# 構造体に配列要素が含まれません。In safe code, a C# struct that contains an array does not contain the array elements. この場合、構造体には、配列の要素ではなく、その参照が格納されます。Instead, the struct contains a reference to the elements. unsafe のコード ブロックで使われている struct に、固定サイズの配列を埋め込むことができます。You can embed an array of fixed size in a struct when it is used in an unsafe code block.

struct が参照であるため、次の pathName のサイズは配列内の要素の数に依存しません。Size of the following struct doesn't depend on the number of elements in the array, since pathName is a reference:

public struct PathArray
{
    public char[] pathName;
    private int reserved;
}

アンセーフ コードでは、struct に埋め込み配列を含めることができます。A struct can contain an embedded array in unsafe code. 以下の例の fixedBuffer 配列は固定サイズです。In the following example, the fixedBuffer array has a fixed size. fixed ステートメントを使用して、先頭要素へのポインターを確立します。You use a fixed statement to establish a pointer to the first element. このポインターを使用して配列の要素にアクセスします。You access the elements of the array through this pointer. fixed ステートメントによって、fixedBuffer インスタンス フィールドがメモリ内の特定の位置に固定されます。The fixed statement pins the fixedBuffer instance field to a specific location in memory.

internal unsafe struct Buffer
{
    public fixed char fixedBuffer[128];
}

internal unsafe class Example
{
    public Buffer buffer = default;
}

private static void AccessEmbeddedArray()
{
    var example = new Example();

    unsafe
    {
        // Pin the buffer to a fixed location in memory.
        fixed (char* charPtr = example.buffer.fixedBuffer)
        {
            *charPtr = 'A';
        }
        // Access safely through the index:
        char c = example.buffer.fixedBuffer[0];
        Console.WriteLine(c);

        // Modify through the index:
        example.buffer.fixedBuffer[0] = 'B';
        Console.WriteLine(example.buffer.fixedBuffer[0]);
    }
}

要素数 128 の char 配列のサイズは 256 バイトです。The size of the 128 element char array is 256 bytes. 固定サイズの char 型バッファーは、エンコーディングに関係なく常に、1 文字あたり 2 バイトを消費します。Fixed size char buffers always take two bytes per character, regardless of the encoding. これは、char 型のバッファーが、CharSet = CharSet.Auto または CharSet = CharSet.Ansi で API メソッドや構造体にマーシャリングされたときにも当てはまります。This is true even when char buffers are marshaled to API methods or structs with CharSet = CharSet.Auto or CharSet = CharSet.Ansi. 詳細については、「CharSet」を参照してください。For more information, see CharSet.

上記の例は、固定せずに fixed フィールドにアクセスする方法を示しています。この方法は C# 7.3 以降から使用できます。The preceding example demonstrates accessing fixed fields without pinning, which is available starting with C# 7.3.

一般的な固定サイズの配列としては、他にも bool 配列があります。Another common fixed-size array is the bool array. bool 配列内の要素のサイズは常に 1 バイトです。The elements in a bool array are always one byte in size. bool 配列は、ビット配列やバッファーの作成には適していません。bool arrays are not appropriate for creating bit arrays or buffers.

固定サイズ バッファーは System.Runtime.CompilerServices.UnsafeValueTypeAttributeを使用してコンパイルされます。これにより、オーバーフローする可能性があるアンマネージド配列が型に含まれていることが共通言語ランタイム (CLR) に指示されます。Fixed size buffers are compiled with the System.Runtime.CompilerServices.UnsafeValueTypeAttribute, which instructs the common language runtime (CLR) that a type contains an unmanaged array that can potentially overflow. これは stackalloc を使用して作成されたメモリに似ています。これにより、CLR 内でバッファー オーバーラン検出機能が自動的に有効になります。This is similar to memory created using stackalloc, which automatically enables buffer overrun detection features in the CLR. 前の例では、unsafe struct に固定サイズ バッファーがどのようにして存在できるかを示しています。The previous example shows how a fixed size buffer could exist in an unsafe struct.

internal unsafe struct Buffer
{
    public fixed char fixedBuffer[128];
}

Buffer 用にコンパイラで生成された C# は、次のように属性が付けられます。The compiler generated C# for Buffer, is attributed as follows:

internal struct Buffer
{
    [StructLayout(LayoutKind.Sequential, Size = 256)]
    [CompilerGenerated]
    [UnsafeValueType]
    public struct <fixedBuffer>e__FixedBuffer
    {
        public char FixedElementField;
    }

    [FixedBuffer(typeof(char), 128)]
    public <fixedBuffer>e__FixedBuffer fixedBuffer;
}

固定サイズ バッファーは、次の点で通常の配列とは異なります。Fixed size buffers differ from regular arrays in the following ways:

  • unsafe のコンテキストでのみ使用できます。May only be used in an unsafe context.
  • 構造体のインスタンス フィールドのみを指定できます。May only be instance fields of structs.
  • これらは常にベクター (1 次元配列) です。They're always vectors, or one-dimensional arrays.
  • 宣言には、fixed char id[8] などの長さを含める必要があります。The declaration should include the length, such as fixed char id[8]. fixed char id[] は使用できません。You cannot use fixed char id[].

関連項目See also