【语法】!(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.NameCat下方会出现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。

可以看出来!运算符不像?!并不对编译结果产生任何影响,只是让编译器的警告跟随代码逻辑,不发出不必要的警告。

官方文档

posted @ 2021-02-01 18:19  Dirt·in·firework  阅读(421)  评论(0)    收藏  举报