细说可空类型 nullable

可空类型是System.Nullable结构体的实列。一个可空类型代表了相应值类型的正确范围附加null值。这么说来,其实也不是很明子,命题嘛,一般不求易懂,但求准确。

那我就来说说这可空类型吧,上次说到了值类型与引用类型,其中就说到了,值类型是不能为空的,int i=null是错的,值类型为能为空,但我们有时候需要让值类型也可以为空,怎么办呢,那就在值类型的值的范围上扩充一个null值。

  1. 为什么要有可空类型

我们在日常开发中,什么地方需要让值类型也变成可空呢?如果你有试过把数据库内的数据对象化的时候,面对数据库中的字段定义如:image

要转化成对象

隐藏行号 复制代码
  1. public class XXXX
    
  2. {
    
  3.  
  4.     public int id { get; set; }
    
  5.  
  6.     //……
    
  7. 
    
  8. }
    

 

这时候就出现问题了,在数据库中是允许为空的,但是在类设计的时候,int类型就是不允许为空的,你不给它赋值,它也是有默认值0的。怎么办?这与数据库的设计是有冲突的,于是,就必须使用咱们的可空类型,我个人理解这也就是为什么要有可空类型的原因。

  • 怎么表示可空类型

使用可空类型,上面的类就可以写成

隐藏行号 复制代码
  1. public class XXXX
    
  2. {
    
  3.  
  4.     public int? id { get; set; }
    
  5.  
  6.     //……
    
  7. 
    
  8. }
    

 

没看错,就是在int后面加上?号,这就是可空类型的表示,当然还有其它的表示方式

 
  1. Nullable<int> d = null;
    

 

这两种表示方式其实是等效的,就根据喜好和使用场景灵活使用就行。

  • 怎么判断是null还是其它值
  • 对于可空类型,我们可以很简单地使用null与可空类型进行比较,就可能判断变量的值是否为null。如:
    隐藏行号 复制代码 这是一段程序代码。
    1. Nullable<int> d = null;
      
    2. bool isNull = d == null ? true : false; 
      

     

  • 当然,我还有其它的办法与方法来做这同样效果的事,如:
    隐藏行号 复制代码 这是一段程序代码。
    1. Nullable<int> d = null;
      
    2. bool isNull = !d.HasValue; 
      

     

  • 注意,如果HasValue是为false时,使用 var result=d.Value时,会抛出异常System.InvalidOperationException
  • 根据情况,根据需要,灵活使用以上两种判断方法。
  • 可空类型怎么给值类型赋值
  • 可空类型不可以直接转化成值类型,也不可以直接对值类型赋值,如:
    隐藏行号 复制代码 这是一段程序代码。
    1. Nullable<int> d = null;
      
    2. int result = d;//错 
      
    3. int result = (int)d;//错
      

     

    那怎么做呢,最简单的办法就是

    隐藏行号 复制代码 这是一段程序代码。
    1. Nullable<int> d = null;
      
    2. int result = d.GetValueOrDefault();
      

     

    这时result的值为0;

    或者也可以判断是否为空,对它进行赋值

    隐藏行号 复制代码 这是一段程序代码。
    1. Nullable<int> d = null;
      
    2. int result;
      
    3. if (!d.HasValue)
      
    4. {
      
    5.     result = d.Value;
      
    6. }
      

     

    如果可空类型是经过运算给值类型赋值。那就还有一种办法

    隐藏行号 复制代码 这是一段程序代码。
    1. Nullable<int> d = null;
      
    2. int result = d ?? +1; 
      

     

    即使用??进行转意。这是的result的值为1;
  • 反射中的可空类型
  • 我们经常会在反射中使用的可空类型,那怎么来使用可空类型呢?
    隐藏行号 复制代码 这是一段程序代码。
    1. public class NullableTest
      
    2. {
      
    3.     public int? ID { get; set; }
      
    4. }
      

     

隐藏行号 复制代码 这是一段程序代码。
  1. var propertyInfo= typeof(NullableTest).GetProperty("ID");
    

 

查询变量的值时,我们会发现

propertyInfo.PropertyType.NameNullable`1
propertyInfo.PropertyType.IsGenericTypetrue
propertyInfo.PropertyType.IsGenericTypeDefinitionfalse
propertyInfo.PropertyType.GetGenericTypeDefinition().NameNullable`1

我们根本无法使用一般泛型得到泛型基类型的方法GetGenericTypeDefinition()得到可空类型的基类型,此时,我们就需要使用GetGenericArguments()去得到泛型的基础类型。

隐藏行号 复制代码 这是一段程序代码。
  1. var propertyInfo = typeof(NullableTest).GetProperty("ID");
    
  2. if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
    
  3. {
    
  4.     Type[] typeArray = propertyInfo.PropertyType.GetGenericArguments();
    
  5.     Type baseType = typeArray[0];
    
  6. }
    

 

做到这里,我们就可以使用反射来完成任何我们想要的操作了。

转载于:https://www.cnblogs.com/taofh/archive/2009/08/27/1554807.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值