C# 8.0 中是否存在针对 not-null 的 "check and get" 运算符?

Is there "check and get" operator against not-null in C# 8.0?

至于检查类型,我们有一个运算符可以同时有效地做两件事:

if (GetObject() is DateTimeOffset dto)
{
   // use dto here
}

不仅本例中的 dto 是特定类型 DateTimeOffset,而且该值是局部的,并且是完全求值的。

那么,C# 8.0 是否提供类似的运算符来检查非空值?

if (GetPossibleNull() is not null x)
{
  // x is local, evaluated and guaranteed to be not-null
}

您可以使用一个空的 属性 模式 ({}) 来检查变量不是 null

if (GetPossibleNull() is {} x)
{
  // x is local, evaluated and guaranteed to be not-null
}

x is T y 表达式还检查所有类型(引用类型和 Nullable<T>)的 null 值,即使 x 静态类型为 T 已经 - 这适用于 C# 7.0:

class Foobar {}

static Foobar GetPossibleNull() { return null; }

static void Main()
{
    if( GetPossibleNull() is Foobar foobar )
    {
        Console.WriteLine( "GetPossibleNull() returned a non-null value." );    
    }
    else
    {
        Console.WriteLine( "GetPossibleNull() returned null." );
    }
}

当我 运行 这个程序时,我在控制台 window 中看到 "GetPossibleNull() returned null"。

这些变体在 C# 7.3 中也能按预期工作(我现在无法访问 C# 8.0 编译器):

static Nullable<Int32> GetNullInt32() => null;
static Nullable<Int32> GetNonNullInt32() => 123;

static void Main()
{
    if( GetNullInt32() is Int32 nonNullInt )
    {
        Console.WriteLine( "GetNullInt32() returned a non-null value." );    
    }
    else
    {
        Console.WriteLine( "GetNullInt32() returned null." );
    }

    if( GetNonNullInt32() is Int32 nonNullInt )
    {
        Console.WriteLine( "GetNonNullInt32() returned a non-null value." );    
    }
    else
    {
        Console.WriteLine( "GetNonNullInt32() returned null." );
    }
}

输出:

GetNullInt32() returned null.

GetNonNullInt32() returned a non-null value.