【.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变量只能为truefalse。但是,在某些应用程序中,变量值可能未定义或缺失。在这种情况下可以使用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指示可为空值类型的实例是否有基础类型的值。
  • 如果HasValuetrue,则Nullable<T>.Value获取基础类型的值。如果HasValuefalse,则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.GetUnderlyingTypetypeof运算符。以检查实例是否具有可为空的值类型。

三、可为 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 allowed
        Console.WriteLine(nullableString);
} catch (Exception? e) // Not Allowed
{
    Console.WriteLine("error");
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/311428.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch安装Windows版

目录 1.&#xff1a;下载安装包&#xff0c;选择指定的版本&#xff0c;这里选择了7.8.0&#xff0c;官网下载地址&#xff1a; ​编辑 2&#xff1a;下载好之后解压&#xff0c;解压之后是这样的&#xff1a; 3&#xff1a;配置环境变量&#xff0c;跟JDK一样&#xff0c;…

金和OA jc6 GetAttOut SQL注入漏洞复现

0x01 产品简介 金和OA协同办公管理系统软件(简称金和OA),本着简单、适用、高效的原则,贴合企事业单位的实际需求,实行通用化、标准化、智能化、人性化的产品设计,充分体现企事业单位规范管理、提高办公效率的核心思想,为用户提供一整套标准的办公自动化解决方案,以帮助…

大文件分片上传,断点续传,秒传 示例(待更新...)

1.html代码 <template><div class="card content-box"><el-upload ref="upload" class="upload-demo" action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15":limit="1" :on-change=&quo…

Springboot+vue的毕业论文管理系统(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的毕业论文管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的毕业论文管理系统&#xff0c;采用M&#xff08;model&…

并发前置知识一:线程基础

一、通用的线程生命周期&#xff1a;“五态模型” 二、java线程有哪几种状态&#xff1f; New&#xff1a;创建完线程Runable&#xff1a;start(),这里的Runnable包含操作的系统的Running&#xff08;运行状态&#xff09;和Ready&#xff08;上面的可运行状态&#xff09;Blo…

【Kafka-3.x-教程】-【三】Kafka-Broker、Kafka-Kraft

【Kafka-3.x-教程】专栏&#xff1a; 【Kafka-3.x-教程】-【一】Kafka 概述、Kafka 快速入门 【Kafka-3.x-教程】-【二】Kafka-生产者-Producer 【Kafka-3.x-教程】-【三】Kafka-Broker、Kafka-Kraft 【Kafka-3.x-教程】-【四】Kafka-消费者-Consumer 【Kafka-3.x-教程】-【五…

java基础之异常练习题

异常 1.Java 中所有的错误/异常都继承自 Throwable类&#xff1b;在该类的子类中&#xff0c; Error 类表示严重的底层错误&#xff0c; 对于这类错误一般处理的方式是 直接报告并终止程序 &#xff1b; Exception 类表示异常。 2.查阅API&#xff0c;完成以下填空&#xff1a;…

【C#】使用 LINQ 中的 Skip() 和 Take()进行分页,为什么要分页,分页作用是什么

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是是《C#》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握…

Linux 常用进阶指令

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 其他…

【内容管理系统】内容管理系统v1.0.0版本正式上线

目录 背景 体验 技术栈 功能菜单 示例图片 背景 为了开发一个无需开发人员&#xff0c;即可动态修改展示内容的内容管理系统&#xff0c;因此开发了当前的内容管理系统。 体验 体验地址&#xff1a;&#xff08;邮箱注册即可体验&#xff0c;部署的带宽有限&#xff0c…

java通过okhttp方式实现https请求的工具类(绕过证书验证)

目录 一、引入依赖包二、okhttp方式实现的https请求工具类2.1、跳过证书配置类2.2、okhttp方式的 https工具类 三、测试类 一、引入依赖包 引入相关依赖包 <!--okhttp依赖包--> <dependency><groupId>com.squareup.okhttp3</groupId><artifactId>…

C++标准学习--tuple

以下帖子介绍的比较详细&#xff1a; C的 tuple_c tuple-CSDN博客 tuple 是 C11 新标准里的类型&#xff0c;它是一个类似 pair 类型的模板。tuple 是一个固定大小的不同类型值的集合&#xff0c;是泛化的 std::pair。我们也可以把它当做一个通用的结构体来用&#xff0c;不需…

Electron中调用dll

截止目前Electron的官方稳定版本已经更新到了28.1.1。我在创建Electron项目时用的28.0.0版本&#xff0c;后面在项目中有用到调用dll方法的需求&#xff0c;大致的实现就是将后端给的dll文件引入到项目中&#xff0c;安装ffi-napi依赖&#xff0c;然后进行使用。但是在Electron…

js逆向第16例:猿人学第12题入门级js

文章目录 一、前言二、定位关键参数三、代码实现一、前言 任务:抓取这5页的数字,计算加和并提交结果 既然是入门级,那肯定很简单了 二、定位关键参数 控制台查看请求数据,m值应该就是关键参数了 进入堆栈 马上定位到了m值"m": btoa(yuanrenxue + window.pag…

【scala】编译build报错 “xxx is not an enclosing class“

private[sources] val creationTimeMs: Long {val session SparkSession.getActiveSession.orElse(SparkSession.getDefaultSession)require(session.isDefined)private[xxx]是访问权限控制在xxxx包的意思。 解决办法&#xff1a; 把[sources]删掉&#xff0c;或者改成和包名…

Element|Upload结合Progress实现上传展示进度条

背景 &#xff1a; 项目里的 附件上传 题型组件&#xff0c;用户在上传过程中&#xff0c;如果文件较大&#xff0c;上传过程较慢&#xff0c;而又没有一个类似 Loading... 的加载过程的话&#xff0c;会显得干愣愣的&#xff0c;用户体验较差&#xff0c;所以需要添加一个进度…

JDBC初体验(二)——增、删、改、查

本课目标 理解SQL注入的概念 掌握 PreparedStatement 接口的使用 熟练使用JDBC完成数据库的增、删、改、查操作 SQL注入 注入原理&#xff1a;利用现有应用程序&#xff0c;将&#xff08;恶意的&#xff09;SQL命令注入到后台数据库引擎执行能力&#xff0c;它可以通过在…

[C#]winform部署PaddleOCRV3推理模型

【官方框架地址】 https://github.com/PaddlePaddle/PaddleOCR.git 【算法介绍】 PaddleOCR是由百度公司推出的一款开源光学字符识别&#xff08;OCR&#xff09;工具&#xff0c;它基于深度学习框架PaddlePaddle开发。这款工具提供了一整套端到端的文字检测和识别解决方案&a…

灵魂三连问:是5G卡吗?支持5G吗?是5G套餐吗

关于5G的问题&#xff0c;小伙伴们的疑问是不是很多&#xff0c;它和4G到底有什么区别呢&#xff1f;什么是5G卡&#xff1f;什么是5G套餐&#xff1f;支持5G吗&#xff1f;什么是5G基站&#xff1f;我想大家现在一定是晕的&#xff0c;下面小编来给大家解惑&#xff01; 1&…

MySQL中datetime和timestamp的区别

datetime和timestamp的区别 相同点: 存储格式相同 datetime和timestamp两者的时间格式都是YYYY-MM-DD HH:MM:SS 不同点: 存储范围不同. datetime的范围是1000-01-01到9999-12-31. 而timestamp是从1970-01-01到2038-01-19, 即后者的时间范围很小. 与时区关系. datetime是存储…