动态不尊重返回类型
本文关键字:返回类型 动态 | 更新日期: 2023-09-27 18:30:00
我对C#dynamic
关键字很陌生。在我的一个项目中,我试图玩它,但遇到了一些意想不到的行为。我设法用以下代码重现了这种情况:
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();
}
}
我收到一个RuntimeBinderException
,上面写着
"System.DateTime"不包含"Value"的定义。
因此,变量date
被处理为DateTime
而不是DateTime?
。
dynamic
似乎以某种方式忽略了返回类型声明。我应该避免将var
与dynamic
一起使用吗?
因为将dynamic
变量传递给DateOnly
方法,所以返回类型也变为动态的。所以在这种情况下,你的var date
实际上就是dynamic date
。它包含一个装箱的可为null的DateTime
,但装箱不保留"可为null"部分,所以实际上它只是一个装箱DateTime
,它没有Value
属性。所以您应该只执行Console.WriteLine(date)
来打印值。
正如您所看到的,可为null的类型和dynamic
在一起不能很好地发挥作用。。。
有两个问题。一种是CCD_ 18仍然是动态的,因为右手边是动态的表达式。如果您使用特定类型DateTime?
声明了date
,您将不会看到这种情况。另一个问题是,您返回的是一个可为null的值类型,而转换为动态则被视为装箱。可为null的值类型永远不会被这样装箱。基础值类型被展开,因此date
的行为更像是object
类型的引用,该引用可以具有DateTime或为null,而不是对DateTime?
的引用。绑定器然后尝试根据DateTime解析属性Value
,但失败。然而,如果您尝试Console.WriteLine(date)
,它将失败,因为该方法有太多重载。因此,您将不得不执行类似Console.WriteLine((object)date)
的操作,此时,对于这个简单的示例,您还可以将date
声明为object
。
查看您的函数参数,您正在请求一个可为null的类型。DateTime(System.DateTime.Now)是一个值类型,默认情况下值类型不可为null。