Search code examples
c#.netreflection.emitstructlayout

Difference between [StructLayout(LayoutKind.Sequential)] and TypeAttributes.SequentialLayout?


I dynamically build a struct for P/Invoke using

const TypeAttributes typeAttributes = TypeAttributes.Public | 
                                      TypeAttributes.SequentialLayout | 
                                      TypeAttributes.UnicodeClass;
var typeBuilder = moduleBuilder.DefineType("MyType", typeAttributes, typeof(ValueType));

after that, I construct the StructLayoutAttribute and add it to the type like this

ConstructorInfo structLayoutAttributeConstructorInfo = typeof(StructLayoutAttribute).GetConstructor(new[] { typeof(LayoutKind) });

FieldInfo charSetFieldInfo = typeof(StructLayoutAttribute).GetField(nameof(StructLayoutAttribute.CharSet));
CustomAttributeBuilder attr = new CustomAttributeBuilder(structLayoutAttributeConstructorInfo,
                                                         new object[] { LayoutKind.Sequential },
                                                         new FieldInfo[] { charSetFieldInfo },
                                                         new object[] { CharSet.Unicode });
typeBuilder.SetCustomAttribute(structLayoutAttributeBuilder);

which is equivalent to setting

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]

Now, the code works perfectly fine, regardless of whether or not I apply the StructLayoutAttribute to the struct.

Seemingly, setting the attribute is an uncessary redundancy, or am I missing something?


Solution

  • The MSDN documentation for the Type.IsLayoutSequential property states the following (emphasis mine):

    For dynamic types, you can specify TypeAttributes.SequentialLayout when you create the type. In code, apply the StructLayoutAttribute attribute with the LayoutKind.Sequential enumeration value to the type, to specify that layout is sequential.

    So for you the relevant part is the TypeAttributes flag. Specifying the StructLayoutAttribute is redundant or ineffective, respectively.