Description



Description

The target objects for this attribute are non-static fields of classes and structures qualified with the StructLayoutAttribute set to LayoutKind.Explicit. All non-static fields within an object with an explicit layout are required to have this attribute. No static or constant fields within an object with explicit layout are allowed to have this attribute.

The physical layout of the data members of a class or structure is automatically arranged in managed memory. When a managed object is passed as an argument to unmanaged code, the system creates its unmanaged representation. StructLayoutAttribute provides explicit control over this unmanaged representation. FieldOffsetAttribute indicates the offset of a target data member within the unmanaged representation of a class or structure.

If FieldOffsetAttribute instances on target fields of an exported object are set to overlap each other, one field is overwritten by another field. For example, if an integer field has the FieldOffsetAttribute set to 4, and another integer field has the FieldOffsetAttribute set to 6, the last two bytes of the unmanaged representation of the first integer overlap the first two bytes of the second integer. In such a situation writing to one of the fields might corrupt the data in the other.

[Note: See the StructLayoutAttribute class overview for an example that uses FieldOffsetAttribute.]

Compilers are required to not preserve this type in metadata as a custom attribute. Instead, compilers are required to emit it directly in the file format, as described in Partition II of the CLI Specification. Metadata consumers, such as the Reflection API, are required to retrieve this data from the file format and return it as if it were a custom attribute.

Example

using System;

using System.Runtime.InteropServices;



/// <summary>

/// Sample demonstrating the use of the FieldOffsetAttribute class.

/// Use this attribute to specify the physical position of fields in types

/// decorated with StructLayoutAttribute and LayoutKind.Explicit.

/// </summary>

internal class FieldOffsetAttributeSample

{



    private static void Main()

    {

        TIME_ZONE_INFORMATION tzi = new TIME_ZONE_INFORMATION();



        if (GetTimeZoneInformation(out tzi) != -1)

        {

            Console.WriteLine(

                "The current time-zone standard name is '{0}'",

                tzi.StandardName);

            Console.WriteLine(

                "The current time-zone daylight name is '{0}'",

                tzi.DaylightName);

        }

        else

        {

            Console.WriteLine("GetTimeZoneInformation failed.");

        }



        Console.WriteLine();

        Console.WriteLine();

        Console.WriteLine("Press Enter to continue");

        Console.ReadLine();

    }



    // The SYSTEMTIME type to use with TIME_ZONE_INFORMATION.

    [StructLayout(LayoutKind.Explicit)]

    private struct SYSTEMTIME

    {

        [FieldOffset(0)]

        public ushort wYear;

        [FieldOffset(2)]

        public ushort wMonth;

        [FieldOffset(4)]

        public ushort wDayOfWeek;

        [FieldOffset(6)]

        public ushort wDay;

        [FieldOffset(8)]

        public ushort wHour;

        [FieldOffset(10)]

        public ushort wMinute;

        [FieldOffset(12)]

        public ushort wSecond;

        [FieldOffset(14)]

        public ushort wMilliseconds;

    }



    // The TIME_ZONE_INFORMATION type to use with GetTimeZoneInformation. Note

    // that strings must be marshalled as Unicode.

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

    private struct TIME_ZONE_INFORMATION

    {

        [FieldOffset(0)]

        public int Bias;

        [FieldOffset(4)]

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]

        public string StandardName;

        [FieldOffset(68)]

        public SYSTEMTIME StandardDate;

        [FieldOffset(84)]

        public int StandardBias;

        [FieldOffset(88)]

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]

        public string DaylightName;

        [FieldOffset(172)]

        public SYSTEMTIME DaylightDate;

        [FieldOffset(188)]

        public int DaylightBias;

    }



    // Win32 method to retrieve information about the current time-zone.  This

    // is used purely to demonstrate using FieldOffsetAttribute; .NET code

    // would typically use TimeZone.CurrentTimeZone to retrieve the same

    // information.

    [DllImport("kernel32.dll", SetLastError=true)]

    private static extern int GetTimeZoneInformation(

        out TIME_ZONE_INFORMATION lpTimeZoneInformation);



}


The output is


The current time-zone standard name is 'Pacific Standard Time'

The current time-zone daylight name is 'Pacific Standard Time'





Press Enter to continue