【.NET Core】可为null类型详解

2024-01-12 00:52
文章标签 类型 详解 core net null 可为

本文主要是介绍【.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 allowedConsole.WriteLine(nullableString);
} catch (Exception? e) // Not Allowed
{Console.WriteLine("error");
}

这篇关于【.NET Core】可为null类型详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/596279

相关文章

sky-take-out项目中Redis的使用示例详解

《sky-take-out项目中Redis的使用示例详解》SpringCache是Spring的缓存抽象层,通过注解简化缓存管理,支持Redis等提供者,适用于方法结果缓存、更新和删除操作,但无法实现... 目录Spring Cache主要特性核心注解1.@Cacheable2.@CachePut3.@Ca

Python中Json和其他类型相互转换的实现示例

《Python中Json和其他类型相互转换的实现示例》本文介绍了在Python中使用json模块实现json数据与dict、object之间的高效转换,包括loads(),load(),dumps()... 项目中经常会用到json格式转为object对象、dict字典格式等。在此做个记录,方便后续用到该方

SpringBoot请求参数传递与接收示例详解

《SpringBoot请求参数传递与接收示例详解》本文给大家介绍SpringBoot请求参数传递与接收示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋... 目录I. 基础参数传递i.查询参数(Query Parameters)ii.路径参数(Path Va

RabbitMQ 延时队列插件安装与使用示例详解(基于 Delayed Message Plugin)

《RabbitMQ延时队列插件安装与使用示例详解(基于DelayedMessagePlugin)》本文详解RabbitMQ通过安装rabbitmq_delayed_message_exchan... 目录 一、什么是 RabbitMQ 延时队列? 二、安装前准备✅ RabbitMQ 环境要求 三、安装延时队

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

Java中的stream流分组示例详解

《Java中的stream流分组示例详解》Java8StreamAPI以函数式风格处理集合数据,支持分组、统计等操作,可按单/多字段分组,使用String、Map.Entry或Java16record... 目录什么是stream流1、根据某个字段分组2、按多个字段分组(组合分组)1、方法一:使用 Stri

Spring创建Bean的八种主要方式详解

《Spring创建Bean的八种主要方式详解》Spring(尤其是SpringBoot)提供了多种方式来让容器创建和管理Bean,@Component、@Configuration+@Bean、@En... 目录引言一、Spring 创建 Bean 的 8 种主要方式1. @Component 及其衍生注解

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Java利用@SneakyThrows注解提升异常处理效率详解

《Java利用@SneakyThrows注解提升异常处理效率详解》这篇文章将深度剖析@SneakyThrows的原理,用法,适用场景以及隐藏的陷阱,看看它如何让Java异常处理效率飙升50%,感兴趣的... 目录前言一、检查型异常的“诅咒”:为什么Java开发者讨厌它1.1 检查型异常的痛点1.2 为什么说