Kas*_*erg 15 c# nullable pattern-matching c#-7.0
我喜欢pattern-matching在nullable intie 上使用int?:
int t = 42;
object tobj = t;
if (tobj is int? i)
{
System.Console.WriteLine($"It is a nullable int of value {i}");
}
Run Code Online (Sandbox Code Playgroud)
但是,这会导致以下语法错误:
'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}"".");
}
Run Code Online (Sandbox Code Playgroud)
也按预期工作.
(我正在使用c#-7.2并使用.net-4.7.1和.net-4.6.1进行测试)
我认为它与运算符优先级有关.因此,我尝试在几个地方使用括号,但这没有帮助.
为什么会出现这些语法错误,如何避免这些错误呢?
Dav*_*rno 16
各种形式的类型模式:x is T y,case T y等,总是匹配失败时x是null.这是因为null没有类型,所以问"这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}");
}
Run Code Online (Sandbox Code Playgroud)
这会产生更有帮助的:
其他人(github 上的用户@Blue0500)已将此行为标记为错误Roslyn 问题 #20156。针对Roslyn 问题 #20156 的反应,来自微软的Julien Couvreur表示他认为这是设计使然。来自 Microsoft 从事 Roslyn 工作的
Neal Gafter也表示,对于可空类型是 switch 模式的使用,需要更好的诊断。
因此,可以使用以下方法避免错误消息:
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}");
}
Run Code Online (Sandbox Code Playgroud)
除了解析时 的问题tobj is int? i,这仍然留下了为什么允许tobj is int? i或tobj is Nullable<int> i不允许的问题。