最近项目中,常常碰到这个?和??这两个操作符,之前说得不够详细,趁着周末补全来,希望能够给大家带来帮助。

(一)?操作符

我们知道值类型是不肯能为空的,它总是包含值的本身,不会为NULL,这估计也是值类型的由来。 ?应该是为了解决把值类型设置为可空类型而出现的,比如int? y=null这种情况,当数据库设置某个int类型,datetime类型等等,可以为空的时候,?运算符在我们编程中就会非常有用。其实?这个操作符等价于Nullable<T>。看Nullable<T>的源码可以了解到如下信息:

namespace System {
using System.Runtime.InteropServices;
using System.Runtime.Versioning; [Serializable, StructLayout(LayoutKind.Sequential), NonVersionable, __DynamicallyInvokable]
public struct Nullable<T> where T : struct {
private bool hasValue; //这个类似于一个标注位的作用
internal T value;
[NonVersionable, __DynamicallyInvokable]
public Nullable(T value) {
this.value = value;
this.hasValue = true;
} [__DynamicallyInvokable]
public bool HasValue {
[NonVersionable, __DynamicallyInvokable]
get {
return this.hasValue;
}
}
[__DynamicallyInvokable]
public T Value {
[__DynamicallyInvokable]
get {
if (!this.hasValue) {
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
}
return this.value;
}
}
[NonVersionable, __DynamicallyInvokable]
public T GetValueOrDefault() {
return this.value;
} [NonVersionable, __DynamicallyInvokable]
public T GetValueOrDefault(T defaultValue) {
if (!this.hasValue) {
return defaultValue; //返回默认值。
}
return this.value;
} [__DynamicallyInvokable]
public override bool Equals(object other) {
if (!this.hasValue) {
return (other == null);
}
if (other == null) {
return false;
}
return this.value.Equals(other);
} [__DynamicallyInvokable]
public override int GetHashCode() {
if (!this.hasValue) {
return 0;
}
return this.value.GetHashCode();
} [__DynamicallyInvokable]
public override string ToString() {
if (!this.hasValue) {
return "";
}
return this.value.ToString();
} [NonVersionable, __DynamicallyInvokable]
public static implicit operator T? (T value) {
return new T?(value);
} [NonVersionable, __DynamicallyInvokable]
public static explicit operator T(T? value) {
return value.Value;
}
}
}

可以看出该结构表示可以为null的值类型,它本身也是轻量级的,实例是存在栈上的,而且实例大小和原始值类型基本一样的,只是多了一个Boolean字段。仔细阅读上面的源码也可以分析出相关的东西。

(二)?? 空接合操作符

??叫做  null 合并运算符。如果此运算符的左操作数不为 null,则此运算符将返回左操作数;否则返回右操作数。可以用来给变量设置默认值。特别提醒: 记住和空有关的时候,才要去用?? 。如果不会有空的判断,就别用了。因为这个是空的合并运算符。也有人说??是?:的语法糖而已,但是实际上??进行了很大改进,能够更好的支持表达式。

(第二种)??在复合情形中,更好用,和上面类似。

还有就是如何把一个条件表达式,用?和??进行合并。

var flag = tt == null ? 1 : tt.Name;    因为这里进行了为Null的判断,所以可以用??。先写??。然后再来确定左右两边应该写什么。    var flag= tt?.Name??1 ;这个就是合并后的条件表达式

(三)CLR对可空类型支持

C#设计人员想尽一切方法,让可空类型,看起来不要那么另类,看起来像一个一等公民。

看了它的Nullable<T>的代码就知道了,它其实是一个bool类型字段+值类型。其实它很多操作都可以从这里来解释,装箱,拆箱。

CLR会说谎----看下图

C#?和??运算符以及合并条件表达式的更多相关文章

  1. Simplifying Conditional Expressions(简化条件表达式)

    1.Decompose Conditional(分解条件表达式) 2.Consolidate Conditional Expressions(合并条件表达式) 3.Consolidate Duplic ...

  2. shell(shell变量、条件表达式、流程控制)

    本章内容: 变量 运算 if语句 for语句 while语句 break.continue 实例 shell变量 1.shell变量简介 变量是任何一种编程语言都必不可少的组成部分,变量用来存放各种数 ...

  3. Dart学习笔记-运算符-条件表达式-类型转换

    Dart学习笔记-运算符-条件表达式-类型转换 一.运算符 1.算术运算符 + (加)- (减)* (乘)/ (除)~/ (取整) %(取余) 2.关系运算符 == (等等) != (不等) > ...

  4. shell之条件表达式

    conditional expressions are used by the [[ compound command and the test and [ builtin commands. ari ...

  5. Less的条件表达式

    Less的条件表达式 当需要根据表达式,而不是参数的值或数量进行匹配时,条件表达式(Guards)就显得非常有用.如果你熟悉函数式编程的话,对条件表达式也不会陌生. 为了尽可能地接近CSS的语言结构, ...

  6. js值类型转换(boolean/String/number),js运算符,if条件,循环结构,函数,三种弹出框

    js值类型转换 number | string | boolean boolean类型转换 num = 0; var b1 = Boolean(num); console.log(b1) 转化为数字类 ...

  7. if语句的嵌套以及条件运算符和条件表达式(初学者)

    1.当if语句中的执行语句又是if语句时,则构成了if语句的嵌套情形. 其一般形式可表示为: if() { if()……; } 或: if() if()语句1: else 语句2: else if() ...

  8. C# 条件表达式max=(a>b)?a:b;含义

    a?b:c 这个是条件表达式,表示如果a为真,则表达式值为b,如果a为假,则表达式值为c条件表达式具体说明如下条件语句: if(a>b) max=a; else max=b; 可用条件表达式写为 ...

  9. Shell条件表达式

    Shell编程中经常需要判断文件状态.字符串是否相等以及两个数值大小等情况,基于这些比较结果再做执行相关操作.本文主要讲述文件状态.字符串.数值大小的判断比较方法. 文件状态判断 文件状态的判断通常使 ...

随机推荐

  1. Jquery Ajax添加header参数

    在使用ajax请求接口时需要在请求头添加token来进行身份验证,方式如下: $.ajax({ type: 'GET', url: 'http://api.php', dataType: 'json' ...

  2. 如何在pyqt中实现带动画的动态QMenu

    弹出菜单的视觉效果 QLineEdit 原生的菜单弹出效果十分生硬,而且样式很丑.所以照着Groove中单行输入框弹出菜单的样式和动画效果写了一个可以实现动态变化Item的弹出菜单,根据剪贴板的内容是 ...

  3. Python标准库:datetime 时间和日期模块 —— 时间的获取和操作详解

    datetime 时间和日期模块 datetime 模块提供了以简单和复杂的方式操作日期和时间的类.虽然支持日期和时间算法,但实现的重点是有效的成员提取以进行输出格式化和操作.该模块还支持可感知时区的 ...

  4. IDEA学习系列之Module概念

    感谢原文作者:小manong 原文链接:https://www.jianshu.com/p/fcccc37fcb73 简单应用:IDEA Maven创建多个Module相互依赖 1.Module的概念 ...

  5. Android 使用签名的好处【转】

    感谢大佬:https://zhidao.baidu.com/question/360127490062917572.html 平时我们的程序可以在模拟器上安装并运行,是因为在应用程序开发期间,由于是以 ...

  6. linux中shell变量$#等的释义

    linux中shell变量$#,$@,$0,$1,$2的含义解释: 变量说明: 1. $$ Shell本身的PID(ProcessID) 2. $! Shell最后运行的后台Process的PID 3 ...

  7. Web标准和骨架

    Web 标准的好处 1.让Web的发展前景更广阔 2.内容能被更广泛的设备访问 3.更容易被搜寻引擎搜索 4.降低网站流量费用 5.使网站更易于维护 6.提高页面浏览速度 Web 标准构成 Web标准 ...

  8. JSP页面重定向与页面内容转发

    重定向:属于两次请求+响应,客户端浏览器地址栏会改变. 转发:属于一次请求+一次响应,客户端浏览器地址栏不会改变. 重定向: response.setHeader("action" ...

  9. 通过bindservice方式调用服务方法里面的过程

    为什么要引入bindService:目的为了调用服务里面的方法 (1)定义一个服务 服务里面有一个方法需要Activity调用 (2)定义一个中间人对象(IBinder) 继承Binder (3)在o ...

  10. PHP页面编码问题

    页面编码统一MySQL数据库编码.html页面编码.PHP或html文件本身编码要全部一致.1.MySQL数据库编码:建立数据库时指定编码(如gbk_chinese_ci),建立数据表.建立字段.插入 ...