C#4:动态和可空的<>

时间:2010-09-16 16:37:24

标签: c# dynamic nullable

所以我有一些代码在方法之间传递这个匿名对象:

var promo = new
{
    Text = promo.Value,
    StartDate = (startDate == null) ?
        new Nullable<DateTime>() : 
        new Nullable<DateTime>(DateTime.Parse(startDate.Value)),
    EndDate = (endDate == null) ?
        new Nullable<DateTime>() : 
        new Nullable<DateTime>(DateTime.Parse(endDate.Value))
};

接收此匿名对象类型的方法将其类型声明为dynamic

private static bool IsPromoActive(dynamic promo)
{
    return /* check StartDate, EndDate */
}

但是,在运行时,如果StartDateEndDate设置为new Nullable<DateTime>(DateTime.Parse(...)),则会收到此dynamic对象(名为promo)的方法执行此操作:

if (promo.StartDate.HasValue && promo.StartDate > DateTime.Today ||
    promo.EndDate.HasValue && promo.EndDate < DateTime.Today)
{
    return;
}

它抛出异常:

Server Error in '/' Application.
'System.DateTime' does not contain a definition for 'HasValue' 

这里发生了什么?关于Nullable类型和dynamic关键字,我不了解哪些内容?

此代码在我更改之前工作正常我删除了先前存储structTextStartDate的{​​{1}},并将其替换为匿名类型并将其传递为EndDate

1 个答案:

答案 0 :(得分:63)

好问题。您可能不知道的两个事实:

  1. 幕后动态只是对象。也就是说,“动态”变量是一个“对象”变量,带有一个提示编译器的提示,说明“在使用它时对该变量生成动态操作。”

  2. 没有箱装可空的东西。当你装一个int?对象你得到一个空对象引用或一个盒装int。 int周围的可空包装器被丢弃。

  3. 现在应该清楚这里发生了什么。如果促销是动态的,那么promo.StartDate是动态的。这意味着在运行时,它是对象。这意味着如果它是值类型,则将其装箱。这意味着如果它可以为空,则它现在是空引用或盒装非可空值。无论哪种方式,该东西都没有HasValue属性。如果你想知道它的值类型是否可以将null值设置为null,那么检查promo.StartDate是否为null。