一、可空类型(类型?)

1、实现可空类型

C# 中,值类型默认不能赋值为 null
在这里插入图片描述
但是你可以通过在类型后面添加 ? 来使它成为可空类型。这样就可以允许它存储 null 值。

int? i = null;

值类型都可以申明为可空类型,比如

float? f = null;
bool? b = null;

引用类型(如 string、object、array 等)本身允许为 null,所以申明为可空类型意义不大

2、判断是否有值

如果你直接访问 Value 属性,而它为 null,将抛出异常。为了避免异常,应该先用 HasValue 判断。

int? i = null;

Console.WriteLine(i);//如果为空输出null
//Console.WriteLine(i.Value);//如果为空会报错

i = 100;

//如果为空返回false
if(i.HasValue){
    Console.WriteLine(i.Value);
}

3、GetValueOrDefault 安全地获取可空类型的值

GetValueOrDefault() 方法可以用于安全地获取可空类型的值。如果是 null,则返回值类型的默认值(例如 0、false、DateTime.MinValue 等)。

  • 不传参时,返回默认值(例如 0)。
  • 传参时,返回指定的默认值。
int? i = null;
Console.WriteLine(i.GetValueOrDefault());        // 输出 0

// 传递默认值 100
Console.WriteLine(i.GetValueOrDefault(100));    // 输出 100

注意:GetValueOrDefault() 并不会改变 i 的值,它只是安全地返回 i 的值或默认值。


二、空条件运算符(?.

?. 语法是 C# 6.0 引入的 空条件运算符。它允许你在对象为 null 时,不会抛出异常,而是直接返回 null。

1、安全调用字符串

比如你想打印一个字符串str,但是如果 str 为 null,则会抛出异常

string str = null;
Console.WriteLine(str.ToString());//如果为空会抛出异常

所以我们应该加空判断,写成

if(str != null){
    Console.WriteLine(str.ToString());
}

使用?.空条件运算符简写

Console.WriteLine(str?.ToString()); // 如果 str 为 null,则不会抛出异常,直接返回 null

这种写法等价于三元运算符号下面这么写:

str == null ? null : str.ToString();

?. 语法更加简洁。

2、安全调用数组

int[] arrayInt = null;

//Console.WriteLine(arrayInt.Length);//如果为空会抛出异常
//Console.WriteLine(arrayInt[0]);//如果为空会抛出异常

Console.WriteLine(arrayInt?.Length);//如果为空,则不执行 Length,输出 null
Console.WriteLine(arrayInt?[0]);//如果为空,则不执行数组元素访问,输出 null

3、安全调用字符串委托或事件

Action action = null;

// 本来的写法
// if(action != null){
//     action();
// }

//优化简写
action?.Invoke(); // 如果 action 为 null,则不会调用,避免异常

三、空合并操作符 (??

1、定义

语法:

左边值 ?? 右边值

如果左边值为null,就返回右边值,否则返回左边值

其实就是类似下面三元运算符这种逻辑

左边值 != null ? 左边值 : 右边值 

2、可空类型的使用

只要是可以为null的类型都可以用

int? intV = null;
// int intI = intV == null ? 100 : intV.Value;
//简写
int intI2 = intV ?? 100;
Console.WriteLine(intI2);

string str2 = null;
str2 = str2 ?? "默认值";
Console.WriteLine(str2);

3、非可空类型的使用

空合并操作符 ?? 不能直接用于 非可空的值类型,如 int、bool 等,因为这些类型不能为 null。如果尝试这么做,编译器会报错。

比如
在这里插入图片描述
如果你想要实现类似的功能,可以使用三元运算符(?:)来做空值判断:

int intV = 0;  // 非可空类型
int result = intV == 0 ? 100 : intV;  // 使用三元运算符
Console.WriteLine(result); // 输出 100,因为 intV 为 0(假设0表示“空”)

4、多级空合并

空合并操作符 ?? 还可以连用,用于多级判断:

string str1 = null;
string str2 = null;
string str3 = "最终值";

// str1 为 null,继续判断 str2,str2 也为 null,最终返回 str3
string result = str1 ?? str2 ?? str3;
Console.WriteLine(result); // 输出 "最终值"

5、简化 GetValueOrDefault() 的用法

空合并操作符常与可空类型一起使用,就可以简化前面 GetValueOrDefault() 的用法。GetValueOrDefault() 会返回 null 时的默认值,而 ?? 则直接提供你想要的默认值。

比如

int? intV = null;

// 传递默认值 100
// int result = intV.GetValueOrDefault(100);

int result = intV ?? 100; // 结果是 100,因为 intV 为 null
Console.WriteLine(result); // 输出 100

四、null 合并赋值运算符 (??=)

它是 C# 8.0 中引入的新特性。??= 运算符用于将左侧的操作数(变量)与右侧的操作数进行比较,如果左侧值为 null,则将右侧的值赋给左侧变量。否则,左侧变量保持不变。

1、语法:

x ??= y;
  • 如果 x 是 null,则将 y 的值赋给 x。
  • 如果 x 不是 null,则 x 保持原值,不进行赋值。

2、示例:

int? x = null;
int? y = 5;

x ??= y;  // 因为 x 是 null,x 将被赋值为 y 的值,即 5
Console.WriteLine(x);  // 输出 5

x ??= 10;  // 因为 x 现在不为 null,x 保持原值 5
Console.WriteLine(x);  // 输出 5

3、适用场景:

??= 运算符特别适用于处理可能为 null 的可空类型或引用类型的变量。它可以简化代码,避免显式的 if (x == null) 判断。


专栏推荐

地址
【从零开始入门unity游戏开发之——C#篇】
【从零开始入门unity游戏开发之——unity篇】
【制作100个Unity游戏】
【推荐100个unity插件】
【实现100个unity特效】
【unity框架开发】

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信或者加群找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

Logo

分享前沿Unity技术干货和开发经验,精彩的Unity活动和社区相关信息

更多推荐