如果它们不在 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 用于我的结构吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何指定我的 .NET 互操作应该使用哪个 COM 服务器?

COM 互操作中动态代码的内存泄漏

WPF App - MFC App 互操作

使用 COM 互操作将对象从 C# 传递到 VBA

将反射与 COM 互操作一起使用

我可以将 .NET 5 COM 互操作对象与 VB6 连接起来吗?