我们为什么需要可空类型?

场景一  从数据库取到的可空类型的字段值,在程序代码中该如何保存?

假设数据库存在表tb_Message,该表保存发送给客户的Message记录。

tb_Message表字段的定义说明如下图所示。

 

其中,除主键id不允许为空外,其他字段均可以为空。

在实际应用中,向用户发送一条Message时,便会向表中的idtitlemessagesenttime字段写入值,但此时并不会向replytime字段写入值,因为该它的值需在消息被回复时才写入,所以此时该字段会保存null。那么等到消息被回复时,程序代码首先会获取replytime的值再更新,这时便出现了“我们在代码中该怎样保存这样一个可空类型的值?的问题这个问题就算在这里不一定会碰见,在其他地方也是会碰见的)。

下面在代码中简单模拟一下发送消息以及消息被回复时修改replytime值的操作。


新建控制台程序,程序主要代码如下所示。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace NullableTExp
{
    class Program
    {
        static void Main(string[] args)
        {
            Message.SendMessage();
            Thread.Sleep(10000);
            Message.ReplyMessage();
        }
    }
 
    public static class Message
    {
        public static void SendMessage()
        {
            using (TestDBEntities myDbEntity = new TestDBEntities())
            {
                tb_Message tbMessage = new tb_Message();
                tbMessage.title = "wsp";
                tbMessage.message = "你是坏蛋,我要和你决斗,请早点回复我!";
                tbMessage.senttime = System.DateTime.Now;
                myDbEntity.AddTotb_Message(tbMessage);
                int count = myDbEntity.SaveChanges();
                Console.WriteLine("消息发送成功!");
            }
        }
 
        public static void ReplyMessage()
        {
            using (TestDBEntities myDbEntity = new TestDBEntities())
            {
                var query = from message in myDbEntity.tb_Message
                            where message.title == "wsp"
                            select message;
                var m = query.FirstOrDefault();
                m.replytime = System.DateTime.Now;
                myDbEntity.SaveChanges();
                Console.WriteLine("消息有回复啦!");
            }
        }
    }
}

运行程序,一切ok。


下面,我们重点看看ReplyMessage()方法。

ReplyMessage()方法中,查询标题为"wsp"的消息并赋值给匿名变量query,再从匿名变量query取出第一条记录(这里满足条件的也就一条记录)赋值给匿名变量m,并修改m的replytime值为当前系统时间,再将变更保存至数据库。整个过程并没有地方保存可空字段replytime的值,所以就算replytime的值为null也不会出错。

假设,我们在代码中加入下面这行代码:

DateTime t = m.replytime;

编译便会出现错误,提示:

无法将类型“System.DateTime?”隐式转换为“System.DateTime”。存在一个显式转换(是否缺少强制转换?)

出现此错误的原因是:

replytime是可空的时间类型,而t是不可为空的时间类型,将可空的时间类型变量赋值给不可为空的时间类型变量(存在隐式类型转换)是不被编译器允许的。

稍稍修改代码(如下所示),再重新编译代码。

DateTime? t = m.replytime;
此时,一切OK啦。                

加上问号,t 就变成了可空的时间类型。

由此可见,使用可空类型接收数据库的可空字段的值可以使操作得到简化。

 

场景二 向方法传入参数null

现在有下面这样一个方法。

public void DoSomething(int? intParam)
{
    if(intParam==null)
    {
        intParam=xx;//xx为默认设置好的值
    }
    //下面使用intParam进行操作
}
在使用这个方法时,可以传入参数null代表使用默认的值来运算,传入非null的值代表使用传入的值进行计算。

向方法传入可空类型参数可以减少方法的重载。

 

场景三 为方法返回null

看下面的方法。

public int? DoSomething(int? intParam)
{
      if(intParam>1000)
      {
           return null;//表示什么也没干
      }
     else
     {
          //其他操作
      }
}

在这个方法中,返回null代表发方法内部什么都没做,在方法调用处可针对此种情况做一些特殊处理。

 

就写这些了。对于Nullable<.T>的用途我就知道这些。总之,存在就有存在的道理。在开发中,慢慢去体会吧。

补充阅读:可空类型Nullable<T>小结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值