猫王运算符 ?.奇怪的是在明显的情况下无法编译
Elvis operator ?. strangely doesn't compile in obvious cases
此静态方法编译:
public static void Foo<TValue>(Func<TValue> factory = null)
{
factory?.Invoke();
}
为什么不呢?然而,这个不是:
public static void Foo<TValue>(Func<TValue> factory = null)
{
var x = factory?.Invoke();
}
使用 return 值似乎有所不同:
当然,运算符 ?.
不应用于 TValue
类型的操作数,而是应用于 Func<TValue>
类型的操作数,这就是为什么它在不使用表达式值。
非通用案例工作得很好:
public static void Bar(Func<String> factory = null)
{
var x = factory?.Invoke();
}
尝试添加 where TValue: class
以确保 TValue
可以是 null
:
static void Foo<TValue>(Func<TValue> factory = null) where TValue: class
在这种情况下,编译器可以将 x
的类型推断为 TValue
并在需要时将 null
分配给它(例如在 factory == null
的情况下)。
或尝试
static void Foo<TValue>(Func<TValue> factory = null) where TValue: struct
在那种情况下,推导的类型将是 TValue?
。 (致谢 @hvd。)
想想 factory?.Invoke();
应该解析成什么类型。 (如果您不在此处使用 var
,则需要进行练习。)它应该是什么类型?
要判断它是什么类型需要通过这个值的计算方式来思考。如果委托不为空,则需要调用它并将操作解析为 TValue
,即委托 returns。但是,如果委托是 null
,则表达式 factory?.Invoke();
需要解析为 null,因此 TValue
需要是可空类型。那么如果 TValue
不可为空怎么办,如果不是,那么该表达式不能是 TValue
类型,但是 应该 是什么?
此静态方法编译:
public static void Foo<TValue>(Func<TValue> factory = null)
{
factory?.Invoke();
}
为什么不呢?然而,这个不是:
public static void Foo<TValue>(Func<TValue> factory = null)
{
var x = factory?.Invoke();
}
使用 return 值似乎有所不同:
当然,运算符 ?.
不应用于 TValue
类型的操作数,而是应用于 Func<TValue>
类型的操作数,这就是为什么它在不使用表达式值。
非通用案例工作得很好:
public static void Bar(Func<String> factory = null)
{
var x = factory?.Invoke();
}
尝试添加 where TValue: class
以确保 TValue
可以是 null
:
static void Foo<TValue>(Func<TValue> factory = null) where TValue: class
在这种情况下,编译器可以将 x
的类型推断为 TValue
并在需要时将 null
分配给它(例如在 factory == null
的情况下)。
或尝试
static void Foo<TValue>(Func<TValue> factory = null) where TValue: struct
在那种情况下,推导的类型将是 TValue?
。 (致谢 @hvd。)
想想 factory?.Invoke();
应该解析成什么类型。 (如果您不在此处使用 var
,则需要进行练习。)它应该是什么类型?
要判断它是什么类型需要通过这个值的计算方式来思考。如果委托不为空,则需要调用它并将操作解析为 TValue
,即委托 returns。但是,如果委托是 null
,则表达式 factory?.Invoke();
需要解析为 null,因此 TValue
需要是可空类型。那么如果 TValue
不可为空怎么办,如果不是,那么该表达式不能是 TValue
类型,但是 应该 是什么?