I am pretty new to C# dynamic
keyword. In one of my projects I tried to play with it and encountered some unexpected behavior. I managed to reproduce the situation with the following code:
class Program
{
static DateTime? DateOnly(DateTime? time)
{
return time.HasValue ? (System.DateTime?)time.Value.Date : null;
}
static void Main(string[] args)
{
dynamic now = System.DateTime.Now;
var date = DateOnly(now);
Console.WriteLine(date.Value); // error thrown here
Console.Read();
}
}
I get a RuntimeBinderException
saying
'System.DateTime' does not contain a definition for 'Value'.
So the variable date
is treated as DateTime
instead of DateTime?
.
It looks like dynamic
somehow ignores the return type declaration.
Should I avoid using var
with dynamic
?
Because you pass a dynamic
variable to the DateOnly
method, the return type also becomes dynamic. So in this case, your var date
is actually dynamic date
. It contains a boxed nullable DateTime
, but boxing doesn't preserve the "nullable" part, so in fact it's just a boxed DateTime
, which doesn't have a Value
property. So you should just do Console.WriteLine(date)
to print the value.
As you can see, nullable types and dynamic
don't play very well together...
There are two issues. One is that date
is still dynamic because the right hand side is a dynamic expression. If you had declared date
with the specific type DateTime?
you would not see this. The other issue is that you are returning a nullable value type and conversion to dynamic is considered boxing. Nullable value types are never boxed as such. The underlying value type is unwrapped so date
behaves more like a reference of type object
that can either have a DateTime or can be null, not a reference to a DateTime?
. The binder then tries to resolve the property Value
against DateTime and fails. If you try Console.WriteLine(date)
, however it will fail as ambiguous because that method has so many overloads. So you will have to do something like Console.WriteLine((object)date)
, at which point you might as well declare date
as object
for this simple example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With