什么是C#中的属性的StructLayoutAttribute效果?

时间:2015-02-12 21:25:55

标签: c# struct memory-layout

我定义要通过不同设备和不同编程语言之间的通信通道接收和发送的结构。 为此,我使用StructLayoutAttribute在内存中明确定义了它们的布局(顺序,pack = 1 - 如果重要的话)。

从文档中,我知道当struct只包含字段时它可以工作。它似乎也适用于简单的'属性(使用空get; set;)。但是,我不知道是否总是这样。

所以我关于StructLayoutAttribute对属性的影响的问题分为两个:

  1. 简单属性(同样,空get; set;)的行为与字段相同吗?
  2. 其他属性如何表现,例如,他们的get是对其他属性进行计算的属性?他们被忽略了(因为我没有看到他们背后的实际数据项)?他们记得吗?

3 个答案:

答案 0 :(得分:3)

属性没有存储空间。 StructLayoutAttribute根本不会影响他们。

自动属性访问生成的支持字段,该字段受StructLayoutAttribute的限制(因为所有字段都受此属性约束)。但是,没有定义这些字段的顺序。

由于只计算值的get-properties没有存储空间,因此它们不会被封送。

答案 1 :(得分:2)

根据文档和我的测试,FieldOffsetAttribute不能应用于属性。这留下了LayoutKind.Sequential的问题。根据{{​​3}},属性字段最后出现。如果您关心布局,基本上不要使用自动属性。展开它们并注释字段。计算属性不会出现在结构的内存布局中。

答案 2 :(得分:1)

自动属性({get; set;})具有自动创建的公开无法访问的后备字段。实际上,如果使用反射来查看具有auto属性的类的字段,则可以看到该属性存在私有字段。下面的代码打印<Bar>k__BackingField - 一个奇怪的字段名称,但仍然是一个字段名称!

我不能说我在某个地产上试过StructLayoutAttribute。如果它有效,它肯定只是将相同的逻辑应用于支持字段。

using System;
using System.Reflection;

namespace ConsoleApplication10
{
    class Program
    {
        static void Main(string[] args)
        {
            var fields = typeof(Foo).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
            Console.WriteLine(fields[0].Name);
        }
    }

    class Foo
    {
        public int Bar { get; set; }
    }
}