You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#中能否实现类似C语言的内嵌固定大小数组?

在C#中实现类内嵌入固定大小数组的方案

要让固定大小数组直接嵌入类实例的内存中(而非作为独立堆对象),C#提供了明确的实现方式,不用完全依赖编译器的不确定优化:

1. 不安全代码中使用fixed关键字

这是最接近C++内置数组行为的方式,数组会直接嵌入类的内存布局,但需要满足两个前提:开启unsafe编译选项,且SomeType是非托管类型(即值类型且不含任何引用类型成员)。

示例代码:

private unsafe class SomeClass : SomeSuperClass {
    // 数组直接嵌入类实例,无额外堆分配
    private fixed SomeType children[256];
    
    // 访问示例(需在unsafe上下文中)
    public unsafe void SetChild(int index, SomeType value) {
        if (index < 0 || index >= 256) throw new ArgumentOutOfRangeException(nameof(index));
        fixed (SomeType* ptr = children) {
            ptr[index] = value;
        }
    }
}

2. 用结构体封装固定大小数组(安全代码)

如果不想使用unsafe上下文,可以定义一个包含固定大小数组的结构体,结构体的内存会嵌入到类实例中。同样要求SomeType是非托管类型(C# 10+支持结构体内部直接声明固定大小数组)。

示例代码:

// 定义固定大小数组的结构体
[StructLayout(LayoutKind.Sequential)]
public struct FixedArray256<T> where T : unmanaged {
    private T _items[256];
    
    // 通过Span<T>安全访问数组元素
    public Span<T> AsSpan() => _items.AsSpan();
    public ref T this[int index] => ref _items[index];
}

// 在类中使用该结构体
private class SomeClass : SomeSuperClass {
    private FixedArray256<SomeType> children;
    
    // 访问示例
    public void SetChild(int index, SomeType value) {
        if (index < 0 || index >= 256) throw new ArgumentOutOfRangeException(nameof(index));
        children[index] = value;
    }
}

关于编译器优化的补充

对于小型数组,JIT编译器可能会在Release模式下进行内联优化,将数组直接嵌入类实例中,但这种优化是不确定的——它依赖于.NET版本、数组大小、类型等因素,无法保证在所有场景下生效。如果需要稳定的内存布局,优先选择上面两种显式实现方式。


内容的提问来源于stack exchange,提问作者Tenobaal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 00:37:40