The word "appropriate" does not refer specifically to these C # declarations. By far, the best way to avoid accidents is to not rely on implementation details of properties and interfaces. This structure should be declared internal and just use simple fields.
The snippet does not show a failure mode, so I have to assume that this is a simplified version of a real declaration that has a problem. A way to verify that C # code gains the right to declare a structure is to verify that the size of the structure and the offset of the last field are the same in both C ++ and C #. Start by writing a small test program to verify that the C ++ version for this snippet should look like this:
#include <Windows.h> #include <stddef.h> struct Base { USHORT size; }; struct Inherited : public Base { BYTE type; }; int main() { int len = sizeof(Inherited); int ofs = offsetof(Inherited, type); return 0; }
And use the debugger to check the variables len and ofs, 4 and 2 in this case. Do the same in C #:
using System; using System.Runtime.InteropServices; class Program { static void Main(string[] args) { var len = Marshal.SizeOf(typeof(Inherited)); var ofs = Marshal.OffsetOf(typeof(Inherited), "<Type>k__BackingField"); } } public interface IBase { ushort Size { get; set; } } [StructLayout(LayoutKind.Sequential)] public struct Inherited : IBase { public ushort Size { get; set; } public byte Type { get; set; } }
Still 4 and 2, so perfect match and pinvoke should be good. When you get a mismatch with the real declaration, navigate your way back in the ofs variable, you will find the member that was declared invalid. Pay attention to the consequences of using the property, forcing to check the bellicose name of the support field. Real code would be much less confusing if you declare a construct using fields instead of properties.
source share