Nullable<T>、Nullable、null、?修饰符的区别
这章我们讨论一下Nullable<T>、Nullable、null、?修饰符的区别
原创文章
Nullable<T>的前世今生
讨论它们之前,我们有必要讨论一下Nullable<T>的前世今生,目的也是为了让我们更好地了解他们的区别,加深印象。
在C#2以前,有一个问题经常会困扰我们,相信大部分人都想过此问题。
在数据库中,比如设置一个表如下(电脑表Computer)
| 字段名 | 类型 | 是否允许空值 |
|---|---|---|
| Color | varchar | Y |
| Age | int | N |
| CpuSpeed | int | Y |
| CreateDate | DateTime | Y |
| Power | int | Y |
对于Age是int类型,不能允许空值还好说,因为插入数据库时会提示Age要有值才能插入。对于CpuSpeed、CreateDate、Power都是值类型,在程序中不能设置空值,比如int CpuSpeed=null,是不允许的。
那么我们以前是怎么解决这种问题的存在呢?
答:'给个默认值=空值'
比如,CreateDate=DateTime.MinValue。表示空值。
这种做法虽然开起来不错,但是显然是在程序设计时要规定好的,容易让人困扰。当新的程序员要接手你的代码时,表示很危险。
那么C#怎么解决这种问题的存在呢?答案就在C#2中引入了Nullable<T>
对于上面的CpuSpeed、CreateDate、Power我们可以在C#中这样来定义:
public Nullable
<int>CpuSpeed;
public Nullable<DateTime>CreateDate;
public Nullable<int>Power;
这样,我们就很好的与数据库那边打交道了。
Nullable<T>、Nullable、null、?修饰符的区别
- Nullable
<T>其实就等于?修饰符。比如上面的 public Nullable<int>CpuSpeed;等价于public int? CpuSpeed; - 修饰符?是Nullable
<T>的简写,请参考上面 - Nullable
<T>是一个结构structs,Nullable是一个静态类。他们结构类型上已经不同。也就是说Nullable<T>是值类型,Nullable是引用类型。
可以看到源代码:
public struct Nullable
<T>where T : struct
public static class Nullable
- Nullable其实显得有点多余,因为它更多意义上是修饰了Nullable
<T>的用法。但是Nullable实现了Nullable<T>很多实用功能。 - null是表示空值,与Nullable
<T>、Nullable没有特别的关联。
null、Nullable<T>
我们有必要说一下null、Nullable<T>的关联。
我们都知道,当比较一个值类型==null时,永远都为false,因为null '一般表示引用类型为null'。
用例子来说明一下吧,创建一个电脑Entity类:
public class Computer
{
public string Color;
public int Age;
public int? CpuSpeed;
public DateTime? CreateDate;
public int? Power;
}
我们来试试比较一下null、Nullable<T>的值是否相等。
第一个需要比较的是,如果Nullable<T>有值时,是否与null的判断,如下:
Computer computer1 = new Computer();
computer1.CpuSpeed = new Nullable();
Console.WriteLine("new Nullable()==new Nullable() " + (computer1.CpuSpeed == new Nullable()));
Console.WriteLine("new Nullable()==null " + (computer1.CpuSpeed == null));
我们首先想想,上面会输出什么呢?
new Nullable<int>()==new Nullable<int>() 肯定是true啦,不用说
new Nullable<int>()==null 按照通常的理解,应该是false,但是这里确实输出true。
为什么呢?哈哈哈,这有点意思呢,我们来看看Nullable<T>的源代码吧:
public override bool Equals(object other) {
if (!hasValue) return other == null;
if (other == null) return false;
return value.Equals(other);
}
看第一行,如果没有值并且other为null就返回true。所以我们就明白了为什么新建一个没有值的Nullable<T>时等于null
到此解析结束了。 请转载本文注明转载处与作者。
可以关注本人的公众号,多年经验的原创文章共享给大家。

Nullable<T>、Nullable、null、?修饰符的区别的更多相关文章
- __block和__weak修饰符的区别
block下循环引用的问题 __block本身并不能避免循环引用,避免循环引用需要在block内部把__block修饰的obj置为nil __weak可以避免循环引用,但是其会导致外部对象释放了之后, ...
- iOS中copy和strong修饰符的区别
iOS中copy和strong修饰符的区别 //用copys修饰的生成的都是不可变的对象 ,如果调用可变类型方法的直接报错 @property(nonatomic,copy)NSString * cp ...
- java-权限修饰符的区别
说明:所谓访问权限,是指对象是否可以通过“.”运算符操作自己的变量或通过“.”运算符使用类中的方法. 1.Java中的四种访问修饰符:public.protected.default(无修饰符,默认) ...
- private/默认/protected/public权限修饰符的区别
private/默认/protected/public权限修饰符和面向对象的三大特性的封装性有着密切关系.它们都可以修饰类的成员,其中的默认和public还可以修饰类. 类的成员包括:成员变量.成员方 ...
- Java 语言的类、属性、方法各有哪些修饰符?简述各修饰符的区别
1. 类的修饰符分为:可访问控制符和非访问控制符两种. 可访问控制符是:公共类修饰符 public 非访问控制符有:抽象类修饰符 abstract :最终类修饰符 final 1.公共类修饰符 pub ...
- C#中override和new修饰符的区别
(new)“隐藏”,(override)“覆盖”(重写).不过要弄清楚这两个有什么区别确实也很难,因为子类在使用父类方法时根本看不出区别,子类不管父类是new了还是override了,用的都是父类方法 ...
- java成员变量与局部变量修饰符的区别
成员变量: 可以被 public,static ,protected,default,final修饰. 局部变量:包括方法里的和 代码块里的(静态和非静态) 可以被default, final修饰 参 ...
- C# const和readonly修饰符的区别
const 的概念就是一个包含不能修改的值的变量.常数表达式是在编译时可被完全计算的表达式.因此不能从一个变量中提取的值来初始化常量.如果 const int a = b+1;b是一个变量,显然不能再 ...
- PHP public private protected 三种修饰符的区别
public 表示全局,类内部外部子类都可以访问:private表示私有的,只有本类内部可以使用:protected表示受保护的,只有本类或子类或父类中可以访问:
随机推荐
- Excel 两列单元格合并超级链接的VBA 写法
Excel 单元格 分两列 (B列存放姓名, C列存放链接) 列如: 姓名 学号 博客地址 1309032022 李汉超 http://www.cnblogs.com/Vpygamalion/ 141 ...
- ASP.NET判断是否为手机登录
protected void Page_Load(object sender, EventArgs e) { MobileHandle(); } 页面加载时候判断是否为手机登录 protected v ...
- C# 实现简单仿QQ登陆注册功能
闲来没事,想做一个仿QQ登陆注册的winform,于是利用工作之余,根据自己的掌握和查阅的资料,历时4天修改完成,新手水平,希望和大家共同学习进步,有不同见解希望提出! 废话不多说,进入正题: 先来看 ...
- EF学习笔记-2 EF之支持复杂类型的实现
使用过.NET的小伙伴们知道,在我们的实体模型中,除了一些简单模型外,还有一些复杂类型,如几个简单的类型组合而成的类型:而EF除了在实现基本的增删改查之外,也支持复杂类型的实现. 那么如何手动构造复杂 ...
- git常用命令常用场景
在使用git之前,一直用的是svn版本管理:与svn最大不同的是,git有两个仓库,一个是本地仓库,一个是服务器上共享的仓库:本地仓库是每个开发者自己独有的,即使commit提交也只是提交到本地仓库: ...
- 微服务统一登陆认证怎么做?JWT ?
无状态登录原理 1.1.什么是有状态? 有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如tomcat中的session. 例如登录:用户登 ...
- [HEOI2016/TJOI2016]字符串(后缀数组+二分+主席树/后缀自动机+倍增+线段树合并)
后缀数组解法: 先二分最长前缀长度 \(len\),然后从 \(rnk[c]\) 向左右二分 \(l\) 和 \(r\) 使 \([l,r]\) 的 \(height\geq len\),然后在主席树 ...
- jzoj4235 序列
取前50個數暴力即可 #include<bits/stdc++.h> using namespace std; int n,m,a[100010],q[5]; int main(){ sc ...
- Spring Boot中使用@Scheduled创建定时任务
我们在编写Spring Boot应用中经常会遇到这样的场景,比如:我需要定时地发送一些短信.邮件之类的操作,也可能会定时地检查和监控一些标志.参数等. 创建定时任务 在Spring Boot中编写定时 ...
- Swift 里 Array (二)初始化
init() 函数 在 Array 里 public init() { _buffer = _Buffer() } 以Buffer 是 _ContiguousArrayBuffer 为例. 即初始化了 ...