接线员'?'初始化期间无法应用

时间:2017-09-08 07:24:02

标签: 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'
    }

为什么在非初始化代码执行时初始化代码不能编译,错误代码(CS0023)如何相关?

1 个答案:

答案 0 :(得分:4)

您的问题几乎与Operator '?' cannot be applied to operand of type 'T'重复。

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

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