动态不尊重返回类型

本文关键字:返回类型 动态 | 更新日期: 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似乎以某种方式忽略了返回类型声明。我应该避免将vardynamic一起使用吗?

动态不尊重返回类型

因为将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。