C#可空类型
在C#中,可空类型(Nullable types)允许值类型(比如int
, double
, bool
等)接受null
值。这是特别有用的,因为在很多应用程序中,如数据库交互和数据解析,值类型的字段可能需要表示没有值(null
)的状态。
使用可空类型
可空类型是通过在值类型后面添加一个问号(?
)来声明的。例如:
int? nullableInt = null;
double? nullableDouble = null;
bool? nullableBool = null;
DateTime? nullableDateTime = null;
这里,nullableInt
, nullableDouble
, nullableBool
, nullableDateTime
都是可空类型的变量,一开始它们都被赋予了null
值。
可空类型的属性和方法
可空类型有两个非常有用的属性和几个方法:
HasValue
属性:如果可空类型有一个非null
的值,这个属性返回true
。Value
属性:提供可空类型的值。在尝试访问Value
属性时,如果HasValue
为false
,则会抛出一个InvalidOperationException
。
例如:
int? nullableInt = 5;if (nullableInt.HasValue)
{Console.WriteLine($"The value of nullableInt is: {nullableInt.Value}");
}
GetValueOrDefault()
方法:如果可空类型有值,则返回该值,否则返回默认值(对于数值类型,默认值通常是0
,对于布尔值是false
)。
可空类型与运算符
C# 对可空类型进行了操作符重载,这意味着你可以像使用非可空类型一样使用+
, -
, *
, /
等运算符。如果参与运算的任何一方是null
,那么结果将是null
。
int? a = null;
int? b = 10;
int? c = a + b; // c will be null
可空类型的协变和比较
你可以使用标准的比较运算符(==
, !=
, <
, >
, <=
, >=
)来比较可空类型,如果任一操作数为null
,则比较运算符将返回false
,除了!=
,当两边都是null
时会返回false
。
可空类型与null
合并运算符
null
合并运算符(??
)是用于可空类型的特别有用的运算符。它提供了一种快捷方式来返回可空类型的值,或在可空类型的值为null
时返回一个默认值。
int? nullableInt = null;
int myValue = nullableInt ?? 0; // myValue will be 0
在这个例子中,由于nullableInt
是null
,myValue
将会被赋值为0
。
可空类型和null
条件运算符
从C# 6.0开始,你还可以使用null
条件运算符(?.
),它允许你在尝试访问对象的成员之前检查这个对象是否为null
。如果对象是null
,则不执行成员访问,整个表达式返回null
。
int? length = nullableString?.Length; // 如果nullableString不是null,则返回字符串的长度,否则返回null
总结
可空类型在C#中非常有用,尤其是在处理数据库和其他可能返回不确定值的外部数据源时。通过使用可空类型及其相关的运算符和方法,你可以编写更健壮和错误处理更加优雅的代码。
在C#中,将可空类型作为函数参数意味着你可以传递一个具有特定值的参数,或者如果合适的话,可以传递一个null
值。这在你不确定是否总是有一个合法值传递给函数或者当你想要表示一个可选的或不存在的值时特别有用。
使用可空类型作为函数参数
下面是一个使用可空类型作为函数参数的例子:
public void PrintDetails(string name, int? age)
{if (age.HasValue){Console.WriteLine($"Name: {name}, Age: {age.Value}");}else{Console.WriteLine($"Name: {name}, Age: Not provided");}
}
在这个函数中,age
参数是一个可空的int
类型,这意味着你可以传递一个int
值或者null
给这个参数。函数内部使用HasValue
和Value
属性来确定是否提供了一个有效的年龄值。
调用带有可空类型参数的函数
调用上面的函数可以像下面这样:
PrintDetails("Alice", 25); // 输出: Name: Alice, Age: 25
PrintDetails("Bob", null); // 输出: Name: Bob, Age: Not provided
可空类型作为可选参数
另一个常见的场景是使用可空类型作为函数的可选参数。这样可以让你省略该参数,而不是传递一些特定的值,比如0
、false
或者其他“魔法数字”来表示“无值”。
public void PrintDiscount(string product, double? discount = null)
{if (discount.HasValue){Console.WriteLine($"Product: {product}, Discount: {discount.Value}%");}else{Console.WriteLine($"Product: {product}, No discount applicable");}
}
在这个例子中,discount
参数是可选的,并且默认为null
。这意味着如果你不提供discount
参数,它将默认为null
。
PrintDiscount("Laptop"); // 输出: Product: Laptop, No discount applicable
PrintDiscount("Laptop", 15.0); // 输出: Product: Laptop, Discount: 15%
可空类型参数与方法重载
当你设计函数时,可空类型可以是方法重载的一个替代方案。例如,你可能会有两个方法的重载版本,其中一个接受一个int
参数,另一个不接受任何参数。使用可空类型参数,你可以只有一个方法,而不是重载它。
// 两个重载方法
public void SetAge(int age) { /*...*/ }
public void SetAge() { /*...*/ }// 使用一个可空类型参数的单个方法
public void SetAge(int? age = null)
{if (age.HasValue){// 设置年龄}else{// 采取不设置年龄的行动}
}
小心处理可空类型参数
当使用可空类型作为参数时,务必在函数内部检查参数是否有值,以避免NullReferenceException
异常。这通常是通过HasValue
属性和??
运算符来完成的。
使用可空类型作为参数可以提高函数的灵活性,使得调用者可以更明确地说明是否提供了一个值。然而,也要注意不要过度使用它们,因为在某些情况下,过多的可空类型参数可能会使得函数调用变得复杂并减少代码的可读性。
相关文章:
C#可空类型
在C#中,可空类型(Nullable types)允许值类型(比如int, double, bool等)接受null值。这是特别有用的,因为在很多应用程序中,如数据库交互和数据解析,值类型的字段可能需要表示没有值&…...

R语言:利用biomod2进行生态位建模
在这里主要是分享一个不错的代码,喜欢的可以慢慢研究。我看了一遍,觉得里面有很多有意思的东西,供大家学习和参考。 利用PCA轴总结的70个环境变量,利用biomod2进行生态位建模: #------------------------------------…...
如何学习算法
在不知其所以然的情况下,算法只是一堆离散的机械步骤,缺少背后的思想的支撑, 这些步骤之间就没有一个本质层面上的关联(先知亚里士多德早就指出:学习即联接)。 所以就跟背历史书也没多大区别。然而…...
MFC/QT 一些快要遗忘的细节:
1:企业应用中,MFC平台除了用常见的对话框模式还有一种常用的就是单文档模式, 维护别人的代码,不容易区分,其实找与程序同名的cpp就知道了,比如项目名称为 DoCMFCDemo,那么就看BOOL CDocMFCDemoApp::InitI…...
常见的面试算法题:阶乘、回文、斐波那契数列
1.阶乘算法 Factorial 例如:给出数字5,对其以下的的每个数字相乘,结果等于120 解:递归 Recursive function factorial(n) {// 如果n为0或1,阶乘是1if (n 0 || n 1) {return 1;}// 否则,返回n乘以n-1的…...

微服务 Spring Cloud 7,Nacos配置中心的Pull原理,附源码
目录 一、本地配置二、配置中心1、以Nacos为例:2、Pull模式3、也可以通过Nacos实现注册中心 三、配置中心提供了哪些功能四、如何操作配置中心1、配置注册2、配置反注册3、配置查看4、配置变更订阅 五、主流的微服务注册中心有哪些,如何选择?…...
c#Nettonsoft.net库常用的方法json序列化反序列化
Newtonsoft.Json 是一个流行的 JSON 操作库,用于在 .NET 应用程序中序列化、反序列化和操作 JSON 数据。下面是 Newtonsoft.Json 常用的一些方法: 序列化对象为 JSON 字符串: string json JsonConvert.SerializeObject(obj);var obj new {…...

力扣刷题-二叉树-二叉树的高度与深度
二叉树最大深度 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:3 递归法 本题可以使用前序(中左…...
Vue3新增加的css语法糖
一、deep <template><div class""><el-input /> </div> </template> <style scoped> /* 样式穿透 */ :deep input {background: red; } </style> 二、slotted 子组件修改插槽里面的样式 <template><div clas…...

Windows安装Vmware 虚拟机
目录 一、Vmware 虚拟机介绍 二、Vmware 虚拟机的三种网络模式 2.1桥接模式 2.2仅主机模式 2.3NAT 网络地址转换模式 三、Vmware 虚拟机的安装 一、Vmware 虚拟机介绍 VMware Workstation Pro 是一款可以在个人电脑的操作系统上创建一个完全与主机操作系统隔离的 虚拟机&…...
uniapp地图手动控制地图scale
前言 首次使用uniapp开发地图过程中,发现uniapp地图居然没有提供手动控制地图scale的方法,这个也着实没有想到,查了半天资料,也终于找到一个方法能够比较好的控制scale,做个记录。 代码 要定义一个地图mapÿ…...

Kotlin学习之函数
原文链接 Understanding Kotlin Functions 函数对于编程语言来说是极其重要的一个组成部分,函数可以视为是程序的执行,是真正活的代码,为啥呢?因为运行的时候你必须要执行一个函数,一般从主函数入口,开始一…...

若依启动步骤
1.创建数据库 2.启动redis 3.改后端的数据库连接配置 4.配置redis redis的地址:cmd中ipconfig命令查看 6.启动后端:如下 7.启动前端ruoyi-ui中 先运行npm install,再npm run dev。项目就启动成功了。 用户名:admin 密码&#x…...

qt-C++笔记之两个窗口ui的交互
qt-C笔记之两个窗口ui的交互 code review! 文章目录 qt-C笔记之两个窗口ui的交互0.运行1.文件结构2.先创建widget项目,搞一个窗口ui出来3.项目添加第二个widget窗口出来4.补充代码4.1.qt_widget_interaction.pro4.2.main.cpp4.3.widget.h4.4.widget.cpp4.5.second…...

Redis-核心数据结构
五种数据结构 String结构 String结构应用场景 Hash结构 Hash结构应用场景 List结构 List结构应用场景 Set结构 Set结构应用场景 ZSet有序结构 ZSet有序结构应用场景...

设计模式—结构型模式之外观模式(门面模式)
设计模式—结构型模式之外观模式(门面模式) 外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。 例子 我们的电脑会有很多 组件&am…...
CentOS Stream 9-使用 systemd 管理自己程序时自定义日志路径
systemd 文件 [rootnode1 ~]# cat /etc/systemd/system/spms-wvp.service [Unit] DescriptionWVP service [Service] # 关键配置部分,注意这里的 spms-wvp ,后面需要用 SyslogIdentifierspms-wvp StandardOutputsyslog StandardErrorsyslog Typesimple Environment…...

动态页面调研及设计方案
文章目录 vue2 动态表单、动态页面调研一、form-generator二、ng-form-element三、Variant Form四、form-create vue2 动态表单、动态页面调研 一、form-generator 预览:https://mrhj.gitee.io/form-generator/#/ Vue2 Element UI支持拖拽生成表单不支持其他组件…...

鸿蒙4.0开发笔记之DevEco Studio之配置代码片段快速生成(三)
一、作用 配置代码片段可以让我们在Deveco Studio中进行开发时快速调取常用的代码块、字符串或者某段具有特殊含义的文字。其实现方式类似于调用定义好变量,然而这个变量是存在于Deveco Studio中的,并不会占用项目的资源。 二、配置代码段的方法 1、打…...

HarmonyOS真机调试报错:INSTALL_PARSE_FAILED_USESDK_ERROR处理
文章目录 1、 新建应用时选择与自己真机匹配的sdk版本2、 根据报错提示连接打开处理方案3、查询真机版本对应的**compileSdkVersion** 和 **compatibleSdkVersion** 提示3.1版本之后和3.1版本之前的不同命令(此处为3.0版本)4、根据查询修改参数5、连接成…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
LUA+Reids实现库存秒杀预扣减 记录流水 以及自己的思考
目录 lua脚本 记录流水 记录流水的作用 流水什么时候删除 我们在做库存扣减的时候,显示基于Lua脚本和Redis实现的预扣减 这样可以在秒杀扣减的时候保证操作的原子性和高效性 lua脚本 // ... 已有代码 ...Overridepublic InventoryResponse decrease(Inventor…...
Easy Excel
Easy Excel 一、依赖引入二、基本使用1. 定义实体类(导入/导出共用)2. 写 Excel3. 读 Excel 三、常用注解说明(完整列表)四、进阶:自定义转换器(Converter) 其它自定义转换器没生效 Easy Excel在…...

spring boot使用HttpServletResponse实现sse后端流式输出消息
1.以前只是看过SSE的相关文章,没有具体实践,这次接入AI大模型使用到了流式输出,涉及到给前端流式返回,所以记录一下。 2.resp要设置为text/event-stream resp.setContentType("text/event-stream"); resp.setCharacter…...