在 C# 中,可以使用 fixed 语句在数据结构中创建带有固定大小数组的缓冲区。 使用现有代码(如使用其他语言、预先存在的 DLL 或 COM 项目编写的代码)时,这种方法非常有用。

固定数组可采用允许普通结构成员使用的任何特性或修饰符。 唯一的限制是,数组类型必须是 bool、byte、 char、 short、int、long、sbyte、ushort、uint、ulong、float 或 double。

private fixed char name[30];

在早期版本的 C# 中,声明 C++ 样式的固定大小结构是很困难的,因为包含数组的 C# 结构不包含数组元素。 相反,该结构包含对元素的引用。

C# 2.0 添加了在 struct(当用在 unsafe 代码块中时)中嵌入固定大小的数组的功能。

例如,在 C# 2.0 之前,下面的 struct 的大小为 8 字节。 pathName 数组是对堆分配数组的引用:

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

从 C# 2.0 开始,struct 可以包含嵌入的数组。 在下面的示例中,fixedBuffer 数组有固定的大小。

若要访问数组的元素,应使用 fixed 语句建立指向第一个元素的指针。 fixed 语句将 fixedBuffer 实例固定到内存中的特定位置。

namespace FixedSizeBuffers
{
    internal unsafe struct MyBuffer
    {
        public fixed char fixedBuffer[128];
    }

    internal unsafe class MyClass
    {
        public MyBuffer myBuffer = default(MyBuffer);
    }

    internal class Program
    {
        static void Main()
        {
            MyClass myC = new MyClass();

            unsafe
            {
                // Pin the buffer to a fixed location in memory.
                fixed (char* charPtr = myC.myBuffer.fixedBuffer)
                {
                    *charPtr = 'A';
                }
            }
        }
    }
}

128 个元素的 char 数组的大小为 256 字节。 在固定大小的 char 缓冲区中,每个字符始终占用两个字节,而与编码无关。

即使将 char 缓冲区封送到具有 CharSet = CharSet.Auto 或 CharSet = CharSet.Ansi 的 API 方法或结构,也是如此。 有关更多信息,请参见 CharSet

另一种常见的固定大小的数组是 bool 数组。 bool 数组中元素的大小始终为一个字节。 bool 数组不适合于创建位数组或缓冲区。

除了用 stackalloc 创建的内存之外,C# 编译器和公共语言运行时 (CLR) 不执行任何安全缓冲区溢出检查。 与所有不安全代码一样,请谨慎使用。

不安全缓冲区与常规数组在以下方面不同:

  • 不安全缓冲区只能用在不安全上下文中。

  • 不安全缓冲区始终是向量(或一维数组)。

  • 数组的声明应包括其本身长度,如 char id[8]。 而不能使用 char id[]。

  • 不安全缓冲区只能是不安全上下文中的结构的实例字段。