title: Optional parameters in managed C++/CLI methods
body: <p>How can I declare a managed method in C++/CLI that has an optional parameter when used from C#?</p>
  
  <p>I've decorated the parameter with both an <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.optionalattribute.aspx" rel="noreferrer">Optional</a> and a <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.defaultparametervalueattribute.aspx" rel="noreferrer">DefaultParameterValue</a> attribute (see: <a href="http://blogs.msdn.com/b/samng/archive/2009/02/03/named-arguments-optional-arguments-and-default-values.aspx" rel="noreferrer">How default parameter values are encoded</a>), but only the Optional attribute seems to be honored.</p>
  
  <hr>
  
  <p><em>C++/CLI:</em></p>
  
  <pre><code>public ref class MyClass1
  {
   public:
    MyClass1([System::Runtime::InteropServices::Optional]
             [System::Runtime::InteropServices::DefaultParameterValue(2)]
             int myParam1)                                            ↑
    {
      System::Console::WriteLine(myParam1);
    }
  };
  </code></pre>
  
  <p><em>C#:</em></p>
  
  <pre><code>var myInstance1 = new MyClass1();  // compiles and runs
  </code></pre>
  
  <p><em>Output</em>:</p>
  
  <pre><code>0
  </code></pre>
  
  <p><em>Expected Output:</em></p>
  
  <pre><code>2
  </code></pre>
  
  <p><em>Visual C# IntelliSense:</em></p>
  
  <pre><code>MyClass1.MyClass1([int myParam1 = 0]);  // wrong default value
                                    ↑
  </code></pre>
  
  <hr>
  
  <p><strong>Edit:</strong> A closer look with a disassembler reveals that the C++/CLI compiler does indeed not generate the required <code>.param [1] = int32(2)</code> directive. The IL code shown by Reflector is wrong.</p>
  
  <p><em>Reflector:</em></p>
  
  <pre><code>.method public hidebysig specialname rtspecialname instance void .ctor([opt] int32 myParam1) cil managed
  {
      .param [1] = int32(2)  // bug
      ...
  </code></pre>
  
  <p><em>ILDASM:</em></p>
  
  <pre><code>.method public hidebysig specialname rtspecialname instance void .ctor([opt] int32 myParam1) cil managed
  {
      .param [1]
      .custom instance void [System]System.Runtime.InteropServices.DefaultParameterValueAttribute::.ctor(object) = ( 01 00 08 02 00 00 00 00 00 ) 
      ...
  </code></pre>