Skip to content

From corefx's perspective, how should an optional DateTime parameter's default value be encoded in IL? #24574

@stakx

Description

@stakx

This is a follow-up question from dotnet/roslyn#24004 intended to determine whether there is a bug in the C# compiler or the framework. I'd appreciate an answer from corefx's perspective that I can take back to the discussion in the referenced issue.

The following C# program will throw a runtime exception:

class Program
{
    public void Method(System.DateTime arg = default(System.DateTime)) { }

    static void Main()
    {
        var defaultValue = typeof(Program).GetMethod("Method").GetParameters()[0].DefaultValue;
    }
}
Unhandled Exception: System.FormatException: Encountered an invalid type for a default value.
   at System.Reflection.MdConstant.GetValue(MetadataImport scope, Int32 token, RuntimeTypeHandle fieldTypeHandle, Boolean raw)
   at System.Reflection.RuntimeParameterInfo.GetDefaultValueInternal(Boolean raw)
   at System.Reflection.RuntimeParameterInfo.GetDefaultValue(Boolean raw)
   at Program.Main() in ...\Program.cs:line 7

An equivalent program written in VB.NET would work just fine. Unlike the VB.NET compiler, the C# compiler does not emit a [System.Runtime.CompilerServices.DateTimeConstant] custom attribute on the optional parameter; instead, it assigns a default value equalling nullref to the parameter:

IL produced by the C# compiler:

// public void Method(System.DateTime arg = default(System.DateTime))
.method public hidebysig instance void Method([opt] valuetype [mscorlib]System.DateTime arg)
  cil managed 
{
  .param [1] = nullref
  // ...
}

IL produced by the VB.NET compiler:

// Public Shared Sub Method(Optional arg As System.DateTime = Nothing)
.method public instance void Method([opt] valuetype [mscorlib]System.DateTime arg) cil managed 
{
  .param [1]
  .custom instance void [mscorlib]System.Runtime.CompilerServices.DateTimeConstantAttribute::.ctor(int64) = ( 01 00 00 00 00 00 00 00 00 00 00 )
  // ...
}

In dotnet/roslyn#24004 (comment), @HaloFour said that the exception appears to be a bug in the BCL's reflection code.

So I am left wondering, who is to blame for the runtime exception?

  • the C# compiler, because it does not emit the [System.Runtime.CompilerServices.DateTimeConstant] attribute that the BCL reflection code apparently expects for optional DateTime parameters; or
  • the implementation of ParameterInfo.DefaultValue in the BCL, which should allow .param [n] = nullref and interpret it as default(DateTime), i. e. a DateTime with .Ticks == 0?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions