C# 中的可为空变量可以从编译器的某个时刻标记为非空吗?

kab*_*aba 4 c# nullable optional-parameters

我用来null表示A? a函数的可选参数应该采用在函数中计算的非空默认值。进入函数后,我检查传入的参数是否anull,如果是,则分配a一个非空值。从那时起,可以安全地假设a是非空的。问题:编译器不知道这一点,现在我必须引用a.Value函数的其余部分,而不是直接的a.

有没有办法告诉编译器a从某个时刻开始实际上是非空的?如果不是,处理此类可选参数的最清晰方法是什么?

示例代码:

using System;

namespace test
{

    public struct A { public int x; };

    class Program
    {

        static void f(A? a = null)
        {
            // Assign the default value.
            if (a == null) a = new A { x = 3 };
            // Now 'a' is non-null for the rest of the function.
            // What I do now:
            Console.WriteLine(a.Value.x);
            // What I'd like to do:
            // * Mark 'a' as non-null somehow.
            // Now can refer to 'a' directly:
            // Console.WriteLine(a.x);
        }

        static void Main(string[] args)
        {
            f();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 6

不,不存在 - 不适用于可为 null 的类型。可空值类型的编译时类型仍然是Nullable<T>,即使编译器知道它将是非空的。

这与可为 null 的引用类型不同,在可为 null 的引用类型中,编译器会跟踪它是否认为变量可能为 null,以便警告取消引用。对于可为 null 的引用类型,不存在“真正的”单独的可为 null 的类型和不可为 null 的类型 - 只有单个引用类型,并指示该值是否可能为 null。

正如问题评论中给出的那样,引入新的不可为空变量的方法实际上是这里唯一的出路。