507 字
3 分钟
C#中问号“?”在语法中的作用以及在Unity中的注意事项
在C#语法中,问号”?“用来判断一个对象是否为空,如果不为空就继续调用,否则不执行任何操作
使用方法 假设有一个对象
public class MyObject {
public string value { get; set; } = "MyObject";
public void Print() {
Debug.Log(value);
}
}
模拟一个情景
MyObject obj = null;
// 这里假如随机到0则创建对象,否则不创建
if (Random.Range(0, 2) == 0) {
obj = new MyObject();
}
// 如果obj不为null则调用Print
if (obj != null) {
obj.Print();
}
使用问号“?”语法替代上面的情景
// 如果obj不为null则调用Print
obj?.Print();
这样起到一个简化代码的作用
“??”的使用 还是上面的MyObject
string tempValue = obj?.value??"temp";
上面的代码相当于
string tempValue;
if (obj != null) {
tempValue = obj.value;
} else {
tempValue = "temp";
}
在Unity中使用时需要注意
public class MyAnimation : MonoBehaviour {
public void Play() {
// ...
}
}
假如我们需要获取一个自定义组件,但并不知道这个组件是否存在,例如:
var myAnimation = GetComponent<MyAnimation>();
myAnimation?.Play(); // 如果存在则调用Play方法
上面的调用是没有问题的,但是需要注意的是,在Unity中调用引擎自带的组件时,那么问题就来了,例如:
var ps = GetComponent<ParticleSystem>();
ps?.Play(); // 这里会报错
报错如下:
按道理说,ps?.Play();
的调用,如果没有找到则不执行,但问题就在,实际上这个ps
对象并不是真正的null
Unity在使用GetComponent
调用内部组件时,即使当前对象没有包含该组件,也不会返回null
,而是返回一个UnityEngine.Object意义上的”空”对象,而UnityEngine.Object重写了==,!=相关的操作符,使得我们使用if去判断时可以正确执行,而使用?
符号去执行时并不会调用重写的操作符因此就出错了
所以在使用GetComponent
调用内部组件时,不要再使用?
符号了,对于自己写的脚本则可以继续使用
C#中问号“?”在语法中的作用以及在Unity中的注意事项
https://jenocn.github.io/posts/code/csharp/questioncharsymbol/