我偶然发现了一个有趣的问题,我没有任何解释,希望有人能解释一下.
在处理可为空的对象(伪)代码时,如下所示(注意:下面的工作片段):
object? obj = GetNullableObject();
if(obj is null) {
return;
}
FunctionRequiringNonNullableObj(obj); // No compile error, object is known to be not null
然而,做同样的事情,比如Long?不会:
long? literal = GetNullableLong();
if(literal is null) {
return;
}
FunctionRequiringNonNullableLong(literal); // Compiler error -> Cannot convert long? to long
不知何故,编译器似乎忽略了文字不能再为空的事实. 我想我遗漏了一些与性能优化有关的东西(或相关的).
实现了两个版本(对象?长?)来重现这个问题. 我的期望是,在这两种情况下,编译器都知道变量不再为空.
using System;
public class Program
{
public static void Main()
{
TestWithObject();
TestWithLiteral();
}
private static void TestWithObject() {
object? obj = ReturnOptionalObject();
if(obj is null) {
Console.WriteLine("Object is null. Returning.");
return;
}
FunctionUsingObject(obj);
}
private static void TestWithLiteral() {
long? literal = ReturnsOptionalLiteral();
if(literal is null) {
Console.WriteLine("Literal is null. Returning.");
return;
}
// Does not work, compiler error
// FunctionUsingLiteral(literal);
}
private static object? ReturnOptionalObject() {
return new object();
}
private static long? ReturnsOptionalLiteral () {
return 123L;
}
private static void FunctionUsingObject(object obj) {
Console.WriteLine("Can access object.");
}
private static void FunctionUsingLiteral(long literal) {
Console.WriteLine("Can access literal.");
}
}