【语法】!(null包容操作符)
!(null forgiving operator)
首先加上nullable的声明,否则将没有相关提示。
#nullable enable
namespace DotNet_5._0_p7
{
class Pet
{
public Pet (Cat? cat, Dog dog)
{
Cat = cat;
Dog = dog;
}
public Cat? Cat;
public Dog Dog;
public override string ToString()
{
return Cat.Name ?? Dog.Name;
}
}
class Cat {
public string Name = "Cat";
}
class Dog
{
public string Name = "Dog";
}
class Program
{
static void Main(string[] args)
{
Pet pet = new Pet(null, null);
Console.WriteLine(pet.ToString());
Console.ReadKey();
}
}
}
在Cat.Name的Cat下方会出现Warning波浪线
Warning CS8602: Dereference of a possibly null reference
new Pet(null, null)的第二个null也会有警告
CS8625 // Cannot convert null literal to non-nullable reference type.
但这只是Warning,实际上还是可以运行程序,然后在Cat.Name处抛出Object reference not set to an instance of an object.的异常。
如果把ToString改成
public override string ToString()
{
if (Cat == null) Cat = new Cat();
return Cat.Name ?? Dog.Name;
}
那将不会有警告,因为编译器已经可以确认Cat不可能为null。
再作这样的修改
private void CheckValid()
{
if (Cat == null) Cat = new Cat();
}
public override string ToString()
{
CheckValid();
return Cat.Name ?? Dog.Name;
}
Cat.Name出现警告,因为编译器无法得知CheckValid的工作,但实际上Cat已经不可能为null。这个时候就可以用上!运算符
Cat!.Name ?? Dog.Name;,这样就能让编译器不发出警告。注意不是?.,Cat?.Name也不会发出警告,但当Cat为null时,Cat?.Name不会抛出异常而是返回null。
可以看出来!运算符不像?,!并不对编译结果产生任何影响,只是让编译器的警告跟随代码逻辑,不发出不必要的警告。

浙公网安备 33010602011771号