C# 可空类型

ops/2024/11/30 8:59:42/

文章目录

  • 前言
  • 一、单问号(?)
  • 二、双问号(??)


前言

  可空类型(Nullable)是一个极具实用性的特性,它为我们处理那些可能出现未赋值情况的数据提供了便捷且合理的方式。而其中,单问号(?)和双问号(??)这两个符号在可空类型的运用中扮演着关键角色,各自有着独特且重要的功能。
在这里插入图片描述

一、单问号(?)

  在 C# 中,像 int、double、bool 等这些基础的数据类型,按照常规情况是无法直接赋值为 null 的。然而,实际编程场景中,尤其是在处理诸如数据库等外部数据源时,常常会遇到数值类型或者布尔型的元素可能未被赋值的情况。这时,单问号(?)就派上用场了,它用于将这些原本不能赋值为 null 的数据类型转变为可空类型(Nullable 类型),意味着这个数据类型被赋予了可以存储 null 值的能力。
例如,以下两种写法是等价的:

int? i = 3;
Nullable<int> i = new Nullable<int>(3);

  通过使用单问号(?),我们定义了一个可空的整型变量 i,它既可以像普通整型变量那样存储 int 类型正常范围内的值(例如 3),也可以存储 null 值。对比普通的整型变量声明:

int i; // 默认值 0
int? ii; // 默认值 null

  可以清晰地看到,普通整型变量在未初始化赋值时,会有一个默认的初始值 0,而可空整型变量 ii 的默认值则是 null,这体现了可空类型在表示未赋值情况方面的独特优势。
  以 Nullable 为例,它读作 “可空的 Int32”,其取值范围非常灵活,不仅可以被赋值为 -2,147,483,648 到 2,147,483,647 之间的任意值(这是 Int32 类型本身正常的取值范围),还可以被赋值为 null 值。类似地,对于 Nullable 变量而言,它打破了常规布尔型只能取 true 或 false 的限制,额外增加了可以赋值为 null 的能力,这在很多场景下都非常有用。
  比如在处理数据库相关操作时,数据库中的布尔型字段可能会出现三种状态:存储值 true、存储值 false,或者该字段未定义(也就是对应程序中的 null 值)。可空类型就能完美地适配这种情况,让我们在程序中可以准确地映射和处理数据库中的数据状态,避免因数据可能未赋值而引发的错误或不合理的默认赋值情况。
  声明一个可空类型(Nullable)有着特定的语法规范,其形式如下:

<data_type>? <variable_name> = null;

  以下是一个展示可空数据类型用法的实例:

using System;
namespace CalculatorApplication
{class NullablesAtShow{static void Main(string[] args){// 声明不同的可空类型变量,并进行不同的赋值操作int? num1 = null;int? num2 = 45;double? num3 = new double?();double? num4 = 3.14157;bool? boolval = new bool?();// 显示值Console.WriteLine("显示可空类型的值: {0}, {1}, {2}, {3}",num1, num2, num3, num4);Console.WriteLine("一个可空的布尔值: {0}", boolval);Console.ReadLine();}}
}

当上述代码被编译和执行时,会输出如下结果:

显示可空类型的值:, 45, , 3.14157
一个可空的布尔值:

  这里可以看到,对于赋值为 null 的可空变量(如 num1 和 num3),在输出时会显示相应的空白占位(具体输出格式可能因不同环境稍有差异,但能体现出其值为 null 的特点),而赋了具体值的可空变量(如 num2 和 num4)则正常输出对应的值,可空布尔型变量 boolval 由于初始化为 null,输出时也相应地体现出未赋值的状态。

二、双问号(??)

  双问号(??)被称为 Null 合并运算符,它主要用于定义可空类型和引用类型的默认值,为类型转换设定了一个预设值,以防可空类型的值为 null。
  Null 合并运算符的特性:如果第一个操作数的值为 null,那么运算符就返回第二个操作数的值;反之,如果第一个操作数不为 null,则返回第一个操作数的值。它还能够把操作数类型隐式转换为另一个可空(或不可空)的值类型的操作数的类型,确保整个运算在类型匹配方面的合理性。
  以下是一个演示 Null 合并运算符用法的实例:

using System;
namespace CalculatorApplication
{class NullablesAtShow{static void Main(string[] args){double? num1 = null;double? num2 = 3.14157;double num3;// 使用 Null 合并运算符进行赋值判断num3 = num1?? 5.34;      // 因为 num1 此时为 null 值,所以返回 5.34Console.WriteLine("num3 的值: {0}", num3);num3 = num2?? 5.34;Console.WriteLine("num3 的值: {0}", num3);Console.ReadLine();}}
}

  当这段代码被编译和执行后,会产生如下结果:

num3 的值: 5.34
num3 的值: 3.14157

  在上述代码中,第一次对 num3 赋值时,由于 num1 的值为 null,根据 Null 合并运算符(??)的规则,就会返回第二个操作数 5.34 作为 num3 的值;而第二次赋值时,num2 的值不为 null(其值为 3.14157),所以直接返回 num2 的值给 num3。
  这种机制在实际编程中有诸多应用场景,比如在从配置文件或者用户输入获取数据时,数据有可能是缺失(对应 null 值)的情况。我们可以利用 Null 合并运算符为这些可能为 null 的可空类型变量设置一个合理的默认值,确保后续程序在使用这些数据时能够有一个明确的、符合预期的值可用,避免因 null 值引发的诸如空指针异常等各种错误。
在这里插入图片描述


http://www.ppmy.cn/ops/137884.html

相关文章

如何使用 Codegen 加速 React Native 开发?

写在前面 在 React Native 开发中&#xff0c;经常需要编写大量的样板代码&#xff0c;例如组件、屏幕、API 等。这些重复性的工作不仅浪费时间&#xff0c;还容易出错。为了解决这个问题&#xff0c;Facebook 推出了一个名为 Codegen 的工具&#xff0c;它可以根据模板和配置…

海盗王用golang重写的AccountServer功能

自从用golang重写了海盗王的网关gateserver以来&#xff0c;一直想把accountserver也重写了&#xff0c;但是一直没有进行。 趁上次刚写好那个golang版的更新器&#xff0c;还有些熟悉&#xff0c;于是把原来AccountServer的C代码重写读了个大概。它原版的写得太过于复杂&#…

【目标跟踪】Anti-UAV数据集详细介绍

Anti-UAV数据集是在2021年公开的专用于无人机跟踪的数据集&#xff0c;该数据集采用RGB-T图像对的形式来克服单个类型视频的缺点&#xff0c;包含了318个视频对&#xff0c;并提出了相应的评估标准&#xff08;the state accurancy, SA)。 文章链接&#xff1a;https://arxiv.…

宝塔Linux面板上传PHP文件或者修改PHP文件,总是转圈圈,其他文件正常,解决办法

目录 问题描述 寻找解决方案 1.重启宝塔面板 2.清理宝塔缓存 3.升级面板 4.ssh远程 5.清空回收站 6.换网络 7. IDE远程编辑 总结&#xff1a; 问题描述 一直用宝塔linux面板&#xff0c;感觉非常好用&#xff0c;点点就能搞定&#xff0c;环境也很好配置。 公司搬家&…

娱乐API:快速生成藏头诗、藏尾诗和藏中诗

引言 诗歌是中国传统文化的重要组成部分&#xff0c;其中藏头诗、藏尾诗和藏中诗因其独特的形式而备受喜爱。为了满足广大文学爱好者的需求&#xff0c;我们推出了一款娱乐API&#xff0c;支持快速生成藏头诗、藏尾诗和藏中诗。本文将详细介绍该API的功能、使用方法以及如何将…

【Docker】Docker配置远程访问

配置Docker的远程访问&#xff0c;你需要按照以下步骤进行操作&#xff1a; 1. 在Docker宿主机上配置Docker守护进程监听TCP端口 Docker守护进程默认只监听UNIX套接字&#xff0c;要实现远程访问&#xff0c;需要修改配置以监听TCP端口。 ‌方法一&#xff1a;修改Docker服务…

使用Alpine镜像作为基础镜像的Dockerfile配置

配置阿里 apk源&#xff1a; /etc/apk/repositories&#xff1a; https://mirrors.aliyun.com/alpine/v3.13/main alpine-v3.13-community安装包下载_开源镜像站-阿里云 或者使用命令 sed -i sdl-cdn.alpinelinux.orgmirrors.aliyun.comg /etc/apk/repositories dockerfil…

观察者模式 (Observer Pattern)

文章目录 观察者模式 (Observer Pattern)原理优点缺点示例代码场景描述1. 定义观察者接口2. 定义目标接口3. 实现具体目标类4. 实现具体观察者类5. 客户端代码输出结果 UML 类图使用场景优化与扩展小结 观察者模式 (Observer Pattern) 观察者模式是一种 行为型设计模式&#x…