Search code examples
c#.netreflectionclr

Obtain non-explicit field offset


I have the following class:

[StructLayout(LayoutKind.Sequential)]
class Class
{
    public int Field1;
    public byte Field2;
    public short? Field3;
    public bool Field4;
}

How can I get the byte offset of Field4 starting from the start of the class data (or object header)?
To illustrate:

Class cls = new Class();
fixed(int* ptr1 = &cls.Field1) //first field
fixed(bool* ptr2 = &cls.Field4) //requested field
{
    Console.WriteLine((byte*)ptr2-(byte*)ptr1);
}

The resulting offset is, in this case, 5, because the runtime actually moves Field3 to the end of the type (and pads it), probably because it its type is generic. I know there is Marshal.OffsetOf, but it returns unmanaged offset, not managed.

How can I retrieve this offset from a FieldInfo instance? Is there any .NET method used for that, or do I have to write my own, taking all the exceptions into account (type size, padding, explicit offsets, etc.)?


Solution

  • With some tricks around TypedReference.MakeTypedReference, it is possible to obtain the reference to the field, and to the start of the object's data, then just subtract. The method can be found in SharpUtils.