Alex Rivera | Logout

What does [opt] mean in MSIL?

Asked 2011-03-31T09:09:11.183
9

I found the "optional parameters" feature in C# 4.0 very interesting, so I tried to figure out how they made it happen. so I wrote a method like this:

private static void A(int a = 5) { }

Compiled it, then decompiled it in IL DASM, this is the IL code:

.method private hidebysig static void  A([opt] int32 a) cil managed
{
  .param [1] = int32(0x00000005)
  // Code size       2 (0x2)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ret
} // end of method Program::A

And it has got this in its metadata:

(1) ParamToken : (08000002) Name : a flags: [Optional] [HasDefault] (00001010) Default: (I4) 5

So I followed the clue and wrote a method like this:

private static void B([Optional, DefaultParameterValue(78)]int b) { }

Compiled it and decompiled it, and I found that the C# compiler generated almost the identical MSIL code for method A and B(except for the name).

As we can see there is no sign of attributes in the IL code and it felt wrong, so I wrote a custom attribute like this:

[AttributeUsage(AttributeTargets.Parameter)]
public class MyTestAttribute : Attribute
{
}

Then used it in method C like this:

private static void C([MyTest]int c) { }

Compiled it and then decompiled it, and hah, I found this:

.method private hidebysig static void  C(int32 c) cil managed
{
  .param [1]
  .custom instance void ConsoleApplication1.MyTestAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       2 (0x2)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ret
} // end of method Program::C

The second line of the method body calls to the ctor of my custom attribute.

So this leads to my doubts:

  1. What does [opt] mean? I mean the one that appears in front of method A and B's parameter.
  2. How come method C calls the constructor of the Attribute that
Edit
Report

1 Answer

2

2 / 3; there are a few attributes that the compiler interprets as IL metadata, not really attributes; it looks like this is the case here; [Serializable] is another example. The data for the default is there: Default: (I4) 5 - not all attributes in code become attributes in the metadata (again, I'm looking at [Serializable] here)


re that point on [Serializable] (comments); here's an example:

[Description("abc")]
class Foo { }

[Serializable]
class Bar { }

for which the core IL is:

.class private auto ansi beforefieldinit Foo
    extends [mscorlib]System.Object
{
    .custom instance void [System]System.ComponentModel.DescriptionAttribute::.ctor(string) = { string('abc') }
    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
    }

}
.class private auto ansi serializable beforefieldinit Bar
    extends [mscorlib]System.Object
{
    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
    }

}

In Foo (for some arbitrary attribute), we get:

.custom instance void [System]System.ComponentModel.DescriptionAttribute::.ctor(string) = { string('abc') }

However this does not apply for [Serializable]; instead, that is part of the type:

.class private auto ansi serializable beforefieldinit Bar
answered 2011-03-31T09:24:28.343

Your Answer