C# 埃尔维斯接线员?。奇怪的是';在明显的情况下不能编译
此静态方法编译:C# 埃尔维斯接线员?。奇怪的是';在明显的情况下不能编译,c#,visual-studio-2015,roslyn,c#-6.0,C#,Visual Studio 2015,Roslyn,C# 6.0,此静态方法编译: public static void Foo<TValue>(Func<TValue> factory = null) { factory?.Invoke(); } 尝试添加其中TValue:class以确保TValue可以为null: static void Foo<TValue>(Func<TValue> factory = null) where TValue: class 在这种情况下,推断的类型将是TValu
public static void Foo<TValue>(Func<TValue> factory = null)
{
factory?.Invoke();
}
尝试添加
其中TValue:class
以确保TValue
可以为null
:
static void Foo<TValue>(Func<TValue> factory = null) where TValue: class
在这种情况下,推断的类型将是
TValue?
。(归功于@hvd)仔细想想什么类型的工厂?.Invoke()代码>应解析为。(如果你没有在这里使用var
,你需要做一个练习。)它应该是什么类型
要确定需要的类型,请仔细考虑如何计算值。如果委托不为null,则需要调用它并将操作解析为TValue
,该值是委托返回的值。但是如果委托是null
该表达式,factory?.Invoke()
,需要解析为null,因此TValue
,需要是可为null的类型。那么,如果TValue
不可为null,如果不可为null,那么该表达式就不能是TValue
类型,但应该是什么呢?如果TValue是值类型,则不能将其赋值为null(在factory==null的情况下)。
这不是真的。它可能是Nullable
“顺便说一句,如果在最后一个示例中使用int而不是String,编译器也会抱怨。”--那根本不是真的。@谢谢,我添加了“non-Nullable”。@hvd哦,当然,类型会被扣除到int?
。我有intx=factoty?.Invoke()
因此出现错误。@AlexD完全正确。这就是为什么其中TValue:struct
也会使它编译:然后编译器知道TValue?
是作为factory?的结果使用的有效类型。Invoke()
?。
通常可以处理不可为空的类型<代码>函数f=null;var i=f?.Invoke()
是桃色的,它给出了i
类型int?
。只是这在泛型中不起作用。没有一种类型可以解析为“maybeT?
,maybeT
”@hvd Indedd,这就是为什么我用我这样的方式来表达这个问题。您需要回答什么类型的factory?.Invoke()代码>解析为。如果您知道它是不可为null的类型,那么您就知道表达式可以解析为TValue?
,但实际上,您不可能知道它解析为什么类型,因此编译器显然也不知道。为了可搜索性,这是一个“null条件运算符”。
public static void Bar(Func<String> factory = null)
{
var x = factory?.Invoke();
}
static void Foo<TValue>(Func<TValue> factory = null) where TValue: class
static void Foo<TValue>(Func<TValue> factory = null) where TValue: struct