在 C# 中如何分配结构数组

Posted

技术标签:

【中文标题】在 C# 中如何分配结构数组【英文标题】:How are arrays of structures allocated in C# 【发布时间】:2021-12-05 05:14:58 【问题描述】:

我正在尝试在 C# 中分配结构数组。例如,

public struct Channel 
    int ChannelId;
    // other stuff goes here... 


public  struct FrameTraffic 
    public int FrameId;
    public int MaxChannels;
    public Channel[] Channels;

    public FrameTraffic(int dummyCS0568 = 0)
    
        this.FrameId = 0;
        MaxChannels = TableMgr.MaxChannels;
        Channels = new Channel[TableMgr.MaxChannels];
    

但是当我去分配一个 FrameTraffic 结构数组时,我看到 Channels 是空的。这告诉我 Channels 是一个引用而不是结构数组。我对么?如果是这样,那么分配 Channels 数组不应该将数组嵌入到结构中,而只是满足结构中的引用。我想要嵌入的结构。有没有办法做到这一点?还是我的假设不正确?

【问题讨论】:

【参考方案1】:

回答您问题的后半部分,忽略任何其他问题。是的,您是正确的,这将是对数组的引用。但是,如果您想将数组嵌入到结构中,您可以使用 fixed sized buffer 和 fixedunsafe 关键字。但是,这只能在设计时知道,也只能是以下值类型,而不是用户定义的结构。

bool, byte, char, short, int, long, sbyte, ushort, uint, ulong, float, or double. 

所以简而言之,你想做的事情是不可能的,你可能需要澄清你为什么需要这个或重新考虑你的问题

【讨论】:

感谢您的确认。我正在尝试预先分配结构以在 Unity 游戏中获得更好的性能。我希望代码看起来尽可能自然,所以我试图避免深入使用复杂的 C#/.NET 方法,并希望有一个直截了当的语法。【参考方案2】:

您需要使用正确的编组属性,并且它需要有一个固定的大小,比如40

public  struct FrameTraffic

    public int FrameId;
    public int MaxChannels;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
    public Channel[] Channels;

【讨论】:

【参考方案3】:

我能够复制空问题,不确定它是否与您的相同:

我认为有两件事可能导致这种情况:

您只是用大小初始化数组,而不是分配任何值 您可能正在使用默认构造而不是您定义的构造初始化 FrameTraffic(这导致了我的实际 NPE)

以下是调整代码的方法:(我有由 TableMgr.MaxChannels 带来的硬编码值,因为我没有)

class Program

    static void Main() 
    
        FrameTraffic fT = new FrameTraffic(0);
        foreach (var item in fT.Channels)
        
            Console.WriteLine(item.ChannelId);
        
        Console.Read();
    


public struct Channel

    public int ChannelId; //missing public exposer if you really want to reassign
    // other stuff goes here... 


public struct FrameTraffic

    public int FrameId;
    
    public Channel[] Channels;

    public FrameTraffic(int dummyCS0568 = 0)
    
        this.FrameId = 0;
        const int MaxChannels = 1;
        //array requires size and its values assigned here 
        Channels = new Channel[MaxChannels] new Channel  ChannelId = 1  ;
    

【讨论】:

是的,你找到的 null 就是我所指的。 @user574771 然后你需要用正确的构造函数初始化它,这就是数组字段没有被初始化的原因,你需要使用你定义的默认参数的构造函数。

以上是关于在 C# 中如何分配结构数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在函数中重新分配结构数组

C# 中锯齿状数组的内存分配与 C++ 中的二维数组内存分配

我如何根据对象标签从这个排序数组中提取碰撞数据并将该对象分配给 C# 中的目标

如何在 C# 中使用 3 个数组分配变量

如何在堆栈上分配数组以获得性能提升?

我应该如何释放类型映射中为 argout 结构数组分配的内存?