我喜欢在pattern-matching
上使用nullable int
,即int?
:
int t = 42;
object tobj = t;
if (tobj is int? i)
{
System.Console.WriteLine($"It is a nullable int of value {i}");
}
但是,这会导致以下语法错误:
'i)'标有红色波浪线。
使用旧运算符is
时表达式编译:
int t = 42;
object tobj = t;
if (tobj is int?)
{
System.Console.WriteLine($"It is a nullable int");
}
string t = "fourty two";
object tobj = t;
if (tobj is string s)
{
System.Console.WriteLine($@"It is a string of value ""{s}"".");
}
也按预期工作。
(我正在使用c#-7.2并使用.net-4.7.1和.net-4.6.1测试)
我认为它与运算符优先级有关。因此,我尝试在几个地方使用括号,但这没有帮助。
为什么会出现这些语法错误,如何避免这些错误呢?
各种形式的类型模式:x is T y
,case T y
等,always fails to match when x
is null
。这是因为null
doesn't have a type,所以问“这是这种类型的null
吗?”是一个毫无意义的问题。
因此t is int? i
或t is Nullable<int> i
没有任何意义作为一种模式:t
是int
,在这种情况下t is int i
无论如何都匹配,或者它是null
,在这种情况下没有类型模式可以导致匹配。
这就是为什么t is int? i
或t is Nullable<int> i
不是,也可能永远不会被编译器支持的原因。
在使用t is int? i
时,您从编译器获得其他错误的原因是,例如, t is int? "it's an int" : "no int here"
是有效的语法,因此编译器对您在此上下文中使用?
作为可空类型的尝试感到困惑。
至于如何避免它们,明显(尽管可能不是很有帮助)的答案是:不要使用可空类型作为类型模式中的类型。更有用的答案需要您解释为什么要尝试这样做。
将您的代码更改为:
int t = 42;
object tobj = t;
if (tobj is Nullable<int> i)
{
Console.WriteLine($"It is a nullable int of value {i}");
}
这会产生更多帮助:
其他人(用户@Blue0500 at github)已将此行为标记为bug Roslyn issue #20156。针对Roslyn issue #20156的反应,来自微软的Julien Couvreur表示他认为这是设计上的。 来自微软工作的Rosz的Neal Gafter也说过better diagnostics are wanted for use of nullable type is switch pattern。
因此,使用以下命令可以避免错误消息:
int t = 42;
object tobj = t;
if (tobj == null)
{
Console.WriteLine($"It is null");
}
else if (tobj is int i)
{
Console.WriteLine($"It is a int of value {i}");
}
除了issues when parsing tobj is int? i
,这仍然留下了为什么不允许tobj is int? i
或tobj is Nullable<int> i
的问题。