-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
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 optionalDateTimeparameters; or - the implementation of
ParameterInfo.DefaultValuein the BCL, which should allow.param [n] = nullrefand interpret it asdefault(DateTime), i. e. aDateTimewith.Ticks == 0?