操作员 '?' 初始化时不能应用

Mat*_*asd 3 c# generics compiler-errors

我的方法ApplyDo我用来变换或计算表达式。在以下示例中,它们在泛型上下文中使用,泛型类型可以是值或引用。编译器允许某些用法,而其他用法则被视为错误。失败和非失败示例的代码类似,只是失败示例是变量初始化。

    public static U Apply<T, U>(this T subject, Func<T, U> f) => f(subject);

    public static void Do<T>(this T subject, Action<T> action) => action(subject);

    public static void SomeMethodA<A>(A a = default(A))
    {
        // OK: apply some operation to 'a'.
        a?.Apply(_ => default(A));

        // OK: apply some operation to 'a' and 'Do' assign result to 'b'.
        A b = default(A);
        a?.Apply(x => x).Do(x => b = x);
        a?.Apply(x => x)?.Do(x => b = x);

        // Bad: apply some operation to 'a' and initialize 'c' and 'd' with result.
        A c = a?.Apply(x => x);  // Error CS0023  Operator '?' cannot be applied to operand of type 'A'
        var d = a?.Apply(x => x);  // Error CS0023  Operator '?' cannot be applied to operand of type 'A'
    }
Run Code Online (Sandbox Code Playgroud)

为什么非初始化代码编译不编译初始化代码,错误代码(CS0023)有什么关系?

Pet*_*iho 5

您的问题几乎是Operator '?'的副本。不能应用于 'T' 类型的操作数

基本问题是它A不可为空。或者至少,不知道可以为空。为了使您的分配工作,编译器必须能够null在短路情况下生成,并将其分配给局部变量。它不能。因此错误。

那么,为什么 的其他用法没有错误a?.?因为这些表达式永远不会分配给任何东西。如果没有赋值,短路就没有问题,因为编译器不必假设某些可能不正确的事情,也不必做一些不可能的事情。