如果它们不在 COM 互操作中执行,我应该将 LayoutKind.Auto 用于我的结构吗?
Posted
技术标签:
【中文标题】如果它们不在 COM 互操作中执行,我应该将 LayoutKind.Auto 用于我的结构吗?【英文标题】:Shoud I use LayoutKind.Auto for my structs if they don't perform in COM Interop? 【发布时间】:2010-12-21 10:54:44 【问题描述】:默认情况下,C# 中的 structs 使用[StructLayout( LayoutKind.Sequential )]
实现,原因基本上是说明这些类型的对象通常用于 COM 互操作,并且它们的字段必须保持它们定义的顺序。类定义了LayoutKind.Auto
。
我的问题是我是否应该将我的结构明确声明为[StructLayout( LayoutKind.Auto )]
,这是否会给我带来任何优于默认设置的好处?我的意思是,如果结构在 stack 上初始化,会有什么不同 - 即 GC 不必移动它们吗?当结构在堆上初始化时也会有所帮助 - 即是某个类的一部分?
【问题讨论】:
【参考方案1】:我能想到的唯一可能的好处是你的结构占用更少的内存。但是如果你一开始就有这么大的结构,你应该probably将它重构为一个类。
一个潜在的问题是您想使用Marshal.PtrToStructure
将您的struct
编组为byte[]
,如何保证字节的顺序符合您的预期?
这样做似乎与您要解决的问题相比,您引入了更多可能的问题...话虽如此,如果对您来说并不重要中的字段顺序,那么就这样做,但请记住,下一个单独来的人可能不会期待它。
【讨论】:
Jeffrey Richter 在他的 CLR 中通过 C# 2 建议将 Layout.Auto 设置为不用于编组方案(如 COM 互操作)的结构。这就是我问这个问题的主要原因。 我给出的例子不一定与COM Interop有关,它可能是某种形式的二进制序列化。【参考方案2】:它可能会给你带来好处,尽管我认为它不会有太大作用。我通常坚持默认设置。
基本上,通过自动布局,CLR 可以选择如何对齐数据,因此可能会为速度做出一些空间权衡(这也取决于平台,在某些情况下保持对齐可能比在其他情况下更重要)。但是,由于结构体也经常在堆栈上使用或作为复合辅助结构体(想想 KeyValuePair),因此默认顺序通常是有意义的。
【讨论】:
以上是关于如果它们不在 COM 互操作中执行,我应该将 LayoutKind.Auto 用于我的结构吗?的主要内容,如果未能解决你的问题,请参考以下文章