猫王经营者?奇怪的是在明显的情况下不编译

Joh*_*ohn 3 c# roslyn c#-6.0 visual-studio-2015

这个静态方法编译:

public static void Foo<TValue>(Func<TValue> factory = null)
{
    factory?.Invoke();
}
Run Code Online (Sandbox Code Playgroud)

为什么不呢?但是,这个不是:

public static void Foo<TValue>(Func<TValue> factory = null)
{
    var x = factory?.Invoke();
}
Run Code Online (Sandbox Code Playgroud)

使用返回值似乎有所不同:

在此输入图像描述

当然,运算符?.不应用于类型的操作数TValue,而是应用于类型的操作数Func<TValue>,这就是为什么它在不使用表达式值时可以工作的原因.

非通用案例工作得很好:

public static void Bar(Func<String> factory = null)
{
    var x = factory?.Invoke();
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*exD 6

尝试添加where TValue: class以确保TValue可以null:

static void Foo<TValue>(Func<TValue> factory = null) where TValue: class
Run Code Online (Sandbox Code Playgroud)

在这种情况下,编译器可以在需要时推导出类型xas TValue并分配null给它(例如在这种情况下factory == null).

或者试试

static void Foo<TValue>(Func<TValue> factory = null) where TValue: struct
Run Code Online (Sandbox Code Playgroud)

在这种情况下,推导出的类型将是TValue?.(信用转到@hvd.)


Ser*_*rvy 6

只要想想factory?.Invoke();应该解决什么类型.(如果你不在var这里使用,你需要做的练习.)它应该是什么类型的?

要确定需要考虑如何计算值的类型.如果委托不为null,则需要调用它并将操作解析为a TValue,即委托返回的任何内容.但是如果委托是null那个表达式,factory?.Invoke();需要解析为null,那么TValue,需要是一个可以为空的类型.那么如果TValue不是可空的话,如果不是,那么那个表达式不能是类型的TValue,那么它应该是什么呢?

  • `?.`通常适用于非可空类型.`Func <int> f = null; var i = f?.Invoke();`只是peachy并给出`i`类型`int?`.只是这在泛型中不起作用.没有类型可以解析为"也许`T?`,也许是'T`". (4认同)