【问题标题】:Nullable datetime compiler limitation可空日期时间编译器限制
【发布时间】:2014-08-03 10:29:57
【问题描述】:

我从 Sql 查询中获取日期信息,如果存在,则将其分配给变量,如果不存在 - 将 date_1 留空。编译器试图预测 date_1 可能为空并阻止使用它,但它没有看到我在使用它之前检查它是否为空。它有什么问题?

第一种情况 - 我使用 bool 标志来表示日期不为空

DateTime date_1;
bool date_1_exists = false;

if (!reader1.IsDBNull(reader1.GetOrdinal("date_1")))
{
    date_1_exists = true;
    date_1 = Convert.ToDateTime(reader1["date_1"]);
}
if (date_1_exists == true)
{
    label1.Text = "date_1: " + date_1.ToString(); // Compiler marks date_1 as error
    label2.Text = "date_2: " + (date_1.AddYears(1)).ToString() + ".";
}

第二种情况 - 我使用 可为空的日期时间

DateTime? date_1;

if (!reader1.IsDBNull(reader1.GetOrdinal("date_1")))
    date_1 = Convert.ToDateTime(reader1["date_1"]);
else
    date_1 = null;

if (date_1.HasValue)
{
    label1.Text = "date_1: " + date_1.ToString(); 
    label2.Text = "date_2: " + (date_1.AddYears(1)).ToString() + "."; // Compiler marks AddYears as error
}

如何使用可以为 null 的 DateTime 变量,但如果它不为 null,则应在进一步计算中使用它。

【问题讨论】:

  • 请显示确切的编译器错误。

标签: asp.net datetime null conditional-statements


【解决方案1】:

2nt情况你只需要告诉他不为空

所以更改此代码

(date_1.AddYears(1)).ToString()

到这里

(((DateTime)date_1).AddYears(1)).ToString()

对于第一种情况,编译器会识别出您尝试“呈现”一个可能没有任何值的值 (DateTime),因此如果您使用第一个 DateTime,请确保所有路径在您的程序逻辑上,为date_1 设置一个值,或使用默认起始值​​定义date_1,例如

DateTime date_1 = default(DateTime);

所以第一个代码可以是

DateTime date_1 = default(DateTime);

if (!reader1.IsDBNull(reader1.GetOrdinal("date_1")))
{
    date_1 = Convert.ToDateTime(reader1["date_1"]);

    label1.Text = "date_1: " + date_1.ToString();
    label2.Text = "date_2: " + (date_1.AddYears(1)).ToString() + ".";

}

或者更接近你的代码

DateTime date_1 = default(DateTime);

if (!reader1.IsDBNull(reader1.GetOrdinal("date_1")))
{
    date_1 = Convert.ToDateTime(reader1["date_1"]);
}

if (date_1 != default(DateTime))
{
    label1.Text = "date_1: " + date_1.ToString();
    label2.Text = "date_2: " + (date_1.AddYears(1)).ToString() + ".";
}

【讨论】:

    【解决方案2】:

    这可能发生在方法内部,因为局部变量不会自动初始化(与成员变量不同)。因此,您可能会收到Use of unassigned local variable 编译器错误。您可以为 date_1 分配默认值并检查它以供将来计算。

    DateTime date_1 = default(DateTime);
    
    //when checking
    if(date_1 != default(DateTime))
    {
        label1.Text = "date_1: " + date_1.ToString(); 
        label2.Text = "date_2: " + (date_1.AddYears(1)).ToString() + ".";
    }
    

    【讨论】:

    • DateTime 是值类型,而不是引用类型(它是结构)。除非您按照第二个示例使用可空版本,否则它永远不能为空:)
    【解决方案3】:

    (有点晚了,但是...)Nullable DateTime 主要是 Nullable struct 并且只知道它的方法,例如 .ToString().GetValueOrDefault()

    当您测试date_1 有一个值时,您可以安全地使用.Value 属性。这将返回一个真实的(不可为空的)DateTime,因此具有所有这些方法。

    所以:

    label2.Text = "date_2: " + date_1.Value.AddYears(1).ToString() + ".";
    

    【讨论】:

      猜你喜欢
      • 2013-02-28
      • 2023-03-05
      • 2021-08-15
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多