What does the IL “.custom instance void [attribute

2019-08-02 17:19发布

问题:

When I used the params keyword for a parameter I found this line in the IL. What I understood from this is that a constructor of the ParamArrayAttribute class is called but I didn't understand what 01 00 00 00 means.

.custom instance void [mscorlib]System.ParamArrayAttribute::.ctor() = (
            01 00 00 00
        )

回答1:

Please refer to section II.21 of the C# specification (version 6) defined in ECMA-335:

Custom attributes are declared using the directive .custom, followed by the method
declaration for a type constructor, optionally followed by a Bytes in parentheses:
CustomDecl ::=
    Ctor [ ‘=’ ‘(’ Bytes ‘)’ ]

The format of the Bytes segment is defined in section II.23.3:

CustomAttrib starts with a Prolog – an unsigned int16, with value 0x0001.
...
Next is a description of the optional “named” fields and properties. This starts with
NumNamed – an unsigned int16 giving the number of “named” properties or fields that
follow. Note that NumNamed shall always be present. A value of zero indicates that there
are no “named” properties or fields to follow (and of course, in this case, the
CustomAttrib shall end immediately after NumNamed).

Examples of various custom attributes are provided in section VI.B.3.

In the case of ParamArrayAttribute, the first two bytes (01 00) are Prolog (in little-endian format), and the last two bytes (00 00) are NumNamed (0 = no arguments).



回答2:

When used to decorate members, attributes may contain initialization parameters that will be sent to the attribute's constructor.

For Instance

[DataMember(EmitDefaultValue = true)]
public int Property { get; set; }

is compiled to

.custom instance void
[System.Runtime.Serialization]System.Runtime.Serialization.DataMemberAttribute::.ctor() = 
( 01 00 01 00 54 02 10 45 6D 69 74 44 65 66 61 75 6C 74 56 61 6C 75 65 01 )

The byte code sequence you see corresponds to the initialization of the EmitDefaultValue parameter.

In your case,

01 00 00 00

is the sequence of bytes used when no parameters are passed to the attribute contructor.