title: Default parameters and reflection: if ParameterInfo.IsOptional then is DefaultValue always reliable?
body: <p>I'm looking at how <code>ParameterInfo.IsOptional</code> is defined (I'm adding default parameter support to an internal IOC framework), and it seems to me that, when true, there is no guarantee that <code>ParameterInfo.DefaultValue</code> (or indeed <code>ParameterInfo.RawDefaultValue</code>) are <em>actually</em> the default values that are to be applied.</p>
  
  <p>If you look at the <a href="http://msdn.microsoft.com/en-us/library/system.reflection.parameterinfo.isoptional.aspx">MSDN example given for <code>IsOptional</code></a>, it seems possible in IL to define a parameter that is optional but for which no default is supplied (given that the <code>ParameterAttributes.HasDefault</code> must be explicitly supplied).  I.e. potentially leading to a situation that a parameter type is, say, <code>Int32</code>, <code>ParameterInfo.IsOptional</code> is true, but <code>ParameterInfo.DefaultValue</code> is null.</p>
  
  <p>My language is C#, therefore I can work on what <em>that</em> compiler will do.  Based on that I can have a simple test as follows (<code>parameter</code> here is a <code>ParameterInfo</code> instance, and the method is meant to return an instance to be used as the runtime argument for the parameter):</p>
  
  <pre><code>if(no_config_value)
  {
    if(!parameter.IsOptional) throw new InvalidOperationException();
    //it's optional, so read the Default
    return parameter.DefaultValue;
  }
  else
    return current_method_for_getting_value();
  </code></pre>
  
  <p>But I'm thinking that some languages (and I want to get this right at the IL-level, rather than just based on what one particular compiler does) can place the onus on the <em>caller</em> to determine the default value to be used, if so, a <code>default(parameter.ParameterType)</code> would need to be in order.</p>
  
  <p>This is where it gets a little more interesting, because <code>DefaultValue</code> is, apparently <code>DBNull.Value</code> (according to <a href="http://msdn.microsoft.com/en-us/library/system.reflection.parameterinfo.defaultvalue.aspx">the documentation for <code>RawValue</code></a>) if there is no default.  Which is no good if the parameter is of type <code>object</code> and <code>IsOptional==true</code>!</p>
  
  <p>Having done a bit more digging, I'm hopeful that the reliable way to solve this is to physically read the <code>ParameterInfo.Attributes</code> member, reading the bitflags individually <strong>first</strong> to check for <code>ParameterAttributes.Optional</code> and <em>then</em> check for <code>ParameterAttributes.Default</code>.  Only if <strong><em>both</em></strong> are present, then reading <code>ParameterInfo.DefaultValue</code> will be correct.</p>
  
  <p>I'm going to start coding and writing tests around this, but I'm asking in the hope that there's someone with more IL knowledge that can confirm my suspicions and hopefully confirm that this'll be correct for any IL-based language (thus avoiding the need to mock up loads of libraries in different languages!).</p>