【.NET Core】可为null类型详解
【.NET Core】可为null类型详解
文章目录
- 【.NET Core】可为null类型详解
- 一、概述
- 二、可为空的值类型
- 2.1 声明和赋值
- 2.2 检查可为空值类型
- 2.3 基础类型与可为空的值类型互换
- 2.4 可为空的值类型装箱和取消装箱
- 2.5 如何确定可为空的值类型
- 三、可为 null 的引用类型

一、概述
null
关键字是表示不引用任何对象的空引用的文字值。null
是引用类型变量的默认值。普通值类型不能为null
,可为空的值类型除外
二、可为空的值类型
可为null
值类型T?
表示其基础值类型T的所有值及额外的null值。基础值类型T
本身不能是可为空的值类型。
任何可为空的值类型都是泛型System.Nullable<T>
结构的实例。可使用以下任何一种互换形式引用具有基础类型T的可为空值类型:Nullable<T>
或T?
。
需要表示基础类型的未定义值时,通常使用可为空的值类型。如:布尔值或bool
变量只能为true
或false
。但是,在某些应用程序中,变量值可能未定义或缺失。在这种情况下可以使用bool?类型。
2.1 声明和赋值
由于值类型可隐式转换为相应的可为空的值类型,因此可以像其基础类型赋值一样,向可为空值类型的变量赋值,还可以分配null
值。具体实例如下:
double? pi=3.1415926;
char? letter='c';
int a=110;
int? ab=a;
bool? flag =null;
int?[] arr= new int?[8];
可为空值类型的默认值表示null
,也就是说,它是其Nullable<T>.HasValue
属性返回false
的实例。
2.2 检查可为空值类型
可将is运算符与类型模式结合使用,既检查null
的可为空值类型的实例,又检索基础类型的值:
int? a = 42;
if(a is int valueOfA){Console.WriteLine($"a is {valueOfA}");
}else{Console.WriteLine("a does not have a value.");
}
始终可以使用以下只读属性来检查和获取可为空值类型变量的值:
Nullable<T>.HasValue
指示可为空值类型的实例是否有基础类型的值。- 如果
HasValue
为true
,则Nullable<T>.Value
获取基础类型的值。如果HasValue
为false
,则Value
属性将引发IvalidOperationException
。
使用HasValue
属性在显示值之前测试变量是否包含该值:
int? b=10;
if(b.HasValue)
{Console.WriteLine($"b is {b.Value}");
}else{Console.WirteLine("b does not have a value.");
}
还可以通过可为空类型与null进行比较,如:
int? bc = 7;
if (bc != null)
{Console.WriteLine($"c is {c.Value}");
}
else
{Console.WriteLine("c does not have a value");
}
2.3 基础类型与可为空的值类型互换
如果要将可为空值类型的值分配给不可以为null
的值类型变量,则可能需要指定要分配的替代null
的值。使用Null
和并操作符??
执行此操作(也可将Nullable<T>.GetValueOrDefault(T)
方法用于相同的目的):
int? pi=3.14;
int b = pi??-1;
Console.WriteLine($"b is {b}");
int? c=null;
int d =c??-1;
Console.WriteLine($"d is {d}");
如果要使用基础值类型的默认值为null
,需要使用Nullable<T>.GetValueOrDefault()
方法。
还可以将可为空的值类型显示强制转换为不可为null
的类型。如下:
int? n = null;
int n2 = (int)n;
在运行时,如果可为空的值类型的值为 null
,则显式强制转换将抛出InvalidOperationException
。不可为null的值类型T
隐式转换为相应的可为空值类型T?
。
2.4 可为空的值类型装箱和取消装箱
可为空值类型的实例T?已装箱;
- 如果
HasValue
返回false
,则生成空引用。 - 如果
HasValue
返回true
,则基础值类型T的对应值将将装箱,而不对Nullable<T>
的实例进行装箱。
可将值类型T
的已装箱值取消装箱到相应的可为空值类型T?
,如示例:
2.5 如何确定可为空的值类型
如果要确定实例是否是可为空的值类型,请不要使用Object.GetType
方法获取要通过前面的代码测试的Type
实例。如果对值类型可为空的实例调用Object.GetType
方法,该实例将装箱到Object。由于对可为空的值类型的非NULL实例的装箱等同于对基础类型的值的装箱,因此GetType
会返回表示可为空的值类型的基础类型的Type
实例。
另外,请勿使用is
运算符来确定实例是否是可为空的值类型。因为无法使用is
运算符区分可为空值类型实例的类型与其基础类型实例。
综合来说,如果要判断可为空值类型,需要使用Nullable.GetUnderlyingType
和typeof
运算符。以检查实例是否具有可为空的值类型。
三、可为 null 的引用类型
由于可为null的感知上下文选择加入代码,可以使用可为null的引用类型。可为null的引用类型,null静态分析警告和null包容运算符是可选的语言功能。
在可为null的感知上下文中:
- 引用类型T的变量必须用非null值进行初始化,并且不能为其分配可能为null的值。
- 引用类型T?的变量可以用null进行初始化,也可以分配null,但是在取消引用之前必须对null进行验证检测。
- 类型为T?的变量m在应用null包含运算符时被认为是非空的。
不可为null的引用类型T和可为null的引用类型T?之间的区别按照编译器对上述规则的解释强制执行的,类型为T的变量和类型为T?的变量由相同的.NET类型表示。
string notNull = "Hello";
string? nullable = default;
notNull = nullable!;
Console.WriteLine(notNull);
变量notNull和nullable都由String
类型表示。因为不可为null
的类型和可为null的类型都存储为相同的类型,所以有几个位置不允许使用可为null的引用类型。
下面几种情况不能使用可为nulll类型:
- 可为 null 的引用类型不能用作基类或实现的接口
- 可为 null 的引用类型不能用于任何对象创建或类型测试表达式
- 可为 null 的引用类型不能是成员访问表达式的类型
public MyClass : System.Object? // not allowed
{
}var nullEmpty = System.String?.Empty; // Not allowed
var maybeObject = new object?(); // Not allowed
try
{if (thing is string? nullableString) // not allowedConsole.WriteLine(nullableString);
} catch (Exception? e) // Not Allowed
{Console.WriteLine("error");
}
相关文章:

【.NET Core】可为null类型详解
【.NET Core】可为null类型详解 文章目录 【.NET Core】可为null类型详解一、概述二、可为空的值类型2.1 声明和赋值2.2 检查可为空值类型2.3 基础类型与可为空的值类型互换2.4 可为空的值类型装箱和取消装箱2.5 如何确定可为空的值类型 三、可为 null 的引用类型 一、概述 nu…...

基于知识图谱的健康知识问答系统
基于知识图谱的健康知识问答系统 引言数据集与技术选型数据集技术选型 系统功能与实现数据导入与图数据库构建问答任务设计与实现1. 实体提取2. 用户意图识别 前端聊天界面与问答系统 结语 引言 随着互联网的发展,人们对健康知识的需求逐渐增加。为了更方便地获取健…...

橘子学K8S03之容器的理解
前面我们知道了容器是通过对一个普通的linux进程进行隔离和限制实现的一种特殊视角下的进程表现。而隔离和限制的实现技术分别是"Namespace"和“Cgroups”,在这两种机制的控制下,我们需要知道容器的本质是一种特殊的进程。 我们现在有了这个认知之后&…...

算法第十二天-矩形区域不超过K的最大数值和
矩形区域不超过K的最大数值和 题目要求 解题思路 来自[宫水三叶] 从题面来看显然是一道[二维前缀和]的题目。本题预处理前缀和的复杂度为O(m* n) 搜索所有子矩阵需要枚举[矩形左上角]和[矩形右下角],复杂度是 O ( m 2 ∗ n 2 ) O(m^2 * n^2) O(m2∗n2),…...

【js】js数组对象去重:
文章目录 一、Map()二、对象访问属性的方法三、indexOf()四、双层for循环 let arrObj [{ name: "小红", id: 1 },{ name: "小橙", id: 1 },{ name: "小黄", id: 4 },{ name: "小绿", id: 3 },{ name: "小青", id: 1 },{ na…...

python高校舆情分析系统+可视化+情感分析 舆情分析+Flask框架(源码+文档)✅
毕业设计:2023-2024年计算机专业毕业设计选题汇总(建议收藏) 毕业设计:2023-2024年最新最全计算机专业毕设选题推荐汇总 🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题ÿ…...

Phaser详解
Phaser是一个相对较新且功能强大的同步原语,它于Java 7中引入,用于协调并行任务的执行。与CyclicBarrier和CountDownLatch等传统的同步工具相比,Phaser提供了更灵活和更高级的功能,特别是在处理动态和可变的并行任务集合时。 1.P…...

2个nodejs进程利用redis 实现订阅发布
1.新建文件 redis_db.js use strict;const redis require(redis); const options {host: "127.0.0.1",port: 6379,password: "123456", // CONFIG SET requirepass "123456" }var array [] for(var i0; i<3; i){const client redis.crea…...

LeetCode——2397. 被列覆盖的最多行数
通过万岁!!! 题目:给你一个二维数组,然后里面是0和1,然后让你从里面选择numSelect列,使得去掉选择的列以后不存在1的行的数量最少。思路: 看到这个题目,本来以为是每一列…...

java通过HttpClient方式实现https请求的工具类(绕过证书验证)
目录 一、引入依赖包二、HttpClient方式实现的https请求工具类三、测试类 一、引入依赖包 引入相关依赖包 <!--lombok用于简化实体类开发--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><option…...

【自学笔记】01Java基础-07面向对象基础-04接口与内部类详解
记录学习Java基础中有关接口类和内部类的知识。 1 接口 interface 关键字用于定义接口类,接口类是一系列方法的声明,一般只有方法的特征没有方法的实现,因此可以被不同的类接入实现,而这些实现可以具有不同的行为(功…...

【cmu15445c++入门】(5)c++中的模板类
一、template模板类 除了模板方法【cmu15445c入门】(4)c中的模板方法 模板也可以用来实现类 二、代码 /*** file templated_classes.cpp* author Abigale Kim (abigalek)* brief Tutorial code for templated classes.*/// Includes std::cout (printing). #include <io…...

MongoDB聚合:$bucket
$bucket将输入文档按照指定的表达式和边界进行分组,每个分组为一个文档,称为“桶”,每个桶都有一个唯一的_id,其值为文件桶的下线。每个桶中至少要包含一个输入文档,也就是没有空桶。 使用 语法 {$bucket: {groupBy…...

从优化设计到智能制造:生成式AI在可持续性3D打印中的潜力和应用
可持续性是现代工业中一个紧迫的问题,包括 3D 打印领域。为了满足环保制造实践日益增长的需求,3D 打印已成为一种有前景的解决方案。然而,要使 3D 打印更具可持续性,还存在一些需要解决的挑战。生成式人工智能作为一股强大的力量&…...

vue3 响应式api中特殊的api
系列文章目录 TypeScript 从入门到进阶专栏 文章目录 系列文章目录一、shallowRef()二、triggerRef()三、customRef()四、shallowReactive()五、shallowReadonly()六、toRaw()七、markRaw()八、effectScope()九、getCurrentScope() 一、shallowRef() shallowRef()是一个新的响…...

【大厂算法面试冲刺班】day2:合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 递归 class Solution {public ListNode mergeTwoLists(ListNode l1, ListNode l2) {if (l1 null) {return l2;}else if (l2 null) {return l1;}else if (l1.val < l2.…...

【JaveWeb教程】(19) MySQL数据库开发之 MySQL数据库操作-DML 详细代码示例讲解
目录 3. 数据库操作-DML3.1 增加(insert)3.2 修改(update)3.3 删除(delete)3.4 总结 3. 数据库操作-DML DML英文全称是Data Manipulation Language(数据操作语言),用来对数据库中表的数据记录进行增、删、改操作。 添加数据(INSERT)修改数据…...

Web前端篇——ElementUI之el-scrollbar + el-backtop + el-timeline实现时间轴触底刷新和一键返回页面顶部
ElementUI之el-scrollbar el-backtop el-timeline实现时间轴触底刷新和一键返回页面顶部。 背景:ElementUI的版本(vue.global.js 3.2.36, index.css 2.4.4, index.full.js 2.4.4) 废话不多说,先看动…...

CAS-ABA问题编码实战
多线程情况下演示AtomicStampedReference解决ABA问题 package com.nanjing.gulimall.zhouyimo.test;import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicStampedReference;/*** @author zho…...

Linux 常用进阶指令
我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! 其他…...

windows通过ssh连接Liunx服务器并实现上传下载文件
连接ssh 输入:ssh空格用户名ip地址,然后按Enter 有可能出现下图提示,输入yes 回车即可 输入 password ,注意密码是不显示的,输入完,再按回车就行了 以上是端口默认22情况下ssh连接,有些公司它…...

【K8S 存储卷】K8S的存储卷+PV/PVC
目录 一、K8S的存储卷 1、概念: 2、挂载的方式: 2.1、emptyDir: 2.2、hostPath: 2.3、NFS共享存储: 二、PV和PVC: 1、概念 2、请求方式 3、静态请求流程图: 4、PV和PVC的生命周期 5、…...

工业智能网关如何保障数据通信安全
工业智能网关是组成工业物联网的重要设备,不仅可以起到数据交换、通信、边缘计算的功能,还可以发挥数据安全保障功能,保障工业物联网稳定、可持续。本篇就为大家简单介绍一下工业智能网关增强和确保数据通信安全的几种措施: 1、软…...

基于Springboot的课程答疑系统(有报告)。Javaee项目,springboot项目。
演示视频: 基于Springboot的课程答疑系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构&…...

操作系统 内存相关
0 内存 cpu和内存的关系 内存覆盖 内存的覆盖是一种在程序运行时将部分程序和数据分为固定区和覆盖区的技术。这种技术的主要目的是为了解决程序较大,无法一次性装入内存导致无法运行的问题。 具体来说,内存的覆盖技术将用户空间划分为以下两个部分&…...

【模拟IC学习笔记】 PSS和Pnoise仿真
目录 PSS Engine Beat frequency Number of harmonics Accuracy Defaults Run tranisent?的3种设置 Pnoise type noise Timeaverage sampled(jitter) Edge Crossing Edge Delay Sampled Phase sample Ratio 离散时间网络(开关电容电路)的噪声仿真方法 PSS PSS…...

IPv6邻居发现协议(NDP)---路由发现
IPv6路由发现(前缀公告) 邻居发现 邻居发现协议NDP(Neighbor Discovery Protocol)是IPv6协议体系中一个重要的基础协议。邻居发现协议替代了IPv4的ARP(Address Resolution Protocol)和ICMP路由器发现(Router Discovery),它定义了使用ICMPv6报文实现地址解析,跟踪邻…...

OpenPLC v3 代码结构
OpenPLC v3 是一个基于 C 的开源实时自动化平台,主要用于控制和自动化行业中的设备。该项目具有以下主要模块: 1. Core:核心模块,提供数据结构和算法实现。 2. Master:主设备模块,实现与从设备通信的接口。…...

安全防御之备份恢复技术
随着计算机和网络的不断普及,人们更多的通过网络来传递大量信息。在网络环境下,还有各种各样的病毒感染、系统故障、线路故障等,使得数据信息的安全无法得到保障。由于安全风险的动态性,安全不是绝对的,信息系统不可能…...

条款39:明智而审慎地使用private继承
1.前言 在之前挑款32曾讨论了C如何将public继承视为is-a关系,在那个例子中我们有个继承体系,其中class Student以public形式继承class Person,于是编译器在必要时刻将Student转换为Persons。。现在,我在以原先那个例子࿰…...