Asp.net 可为空的日期时间编译器限制

Asp.net 可为空的日期时间编译器限制,asp.net,datetime,null,conditional-statements,Asp.net,Datetime,Null,Conditional Statements,我从Sql查询中获取日期信息,如果它存在,则将其分配给一个变量,如果不存在,则将Date_1留空。编译器试图预测date_1可能为null,并阻止使用它,但它并没有看到我在使用它之前检查它是否为null。怎么了 第一种情况-我使用bool标志指示日期不为空 DateTime date_1; bool date_1_exists = false; if (!reader1.IsDBNull(reader1.GetOrdinal("date_1"))) { date_1

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

第一种情况-我使用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,则应在进一步的计算中使用。

2nt情况下您只需告诉他该变量不是null即可

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 = 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() + ".";
}
所以改变这个密码

(date_1.AddYears(1)).ToString()
对此

(((DateTime)date_1).AddYears(1)).ToString()
对于第一种情况编译器认识到您试图“呈现”一个可能没有任何值的值(DateTime),因此如果使用第一个DateTime,请确保程序逻辑上的所有路径,将一个值放置到
date_1
,或使用默认开始值定义
date_1
,例如

DateTime date_1=默认值(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() + ".";
}

这可能发生在方法内部,因为局部变量不会自动初始化(与成员变量不同)。因此,您可能会遇到
使用未分配的局部变量
编译器错误。您可以指定默认值
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主要是一个函数,并且只知道它的方法,例如
.ToString()
.GetValueOrDefault()

当您测试了
date\u 1
是否有值时,就可以安全地使用
.value
属性。这将返回一个实的(不可空的)
DateTime
,因此具有所有这些方法

因此:


请显示确切的编译器错误。
DateTime
是一个值类型,而不是引用类型(它是一个结构)。除非按照第二个示例使用可为空的版本,否则它永远不能为空:)