鉴于以下代码:
string someString = null;
switch (someString)
{
case string s:
Console.WriteLine("string s");
break;
case var o:
Console.WriteLine("var o");
break;
default:
Console.WriteLine("default");
break;
}
为什么开关语句在case var o
上匹配?
我的理解是,当s==null
时,大小写字符串s
不匹配,因为(实际上)(null为字符串)!=null
计算结果为false。VS Code上的IntelliSense告诉我,o
也是一个字符串。有什么想法吗?
类似于:带有空检查的C#7开关外壳
这是因为case
(发帖是因为我喜欢简短的答案。)
我在这里整理了多条twitter评论——这对我来说确实是新鲜事,我希望jaredpar能给出一个更全面的答案,但是;据我所知的简短版本:
case string s:
被解释为if(someString为string){s=(string)someString;..
或if((s=(someString为string))!=null){…}
-其中任何一项都涉及
null
测试-在您的情况下,该测试失败;相反地:
case var o:
其中,编译器将
o
解析为string
就是o=(string)someString
-nonull
test,尽管它在表面上看起来很相似,只是编译器提供了类型。
最后:
default:
这里是无法联系到的,因为上面的案例抓住了一切。这可能是一个编译器错误,因为它没有发出无法访问的代码警告。
我同意这是非常微妙的,微妙的,令人困惑的。但是显然,
case var o
场景使用空传播(o?.Length±0
等)。我同意奇怪的是,这在var o
和string s
之间的工作方式非常不同,但这正是编译器目前所做的。
在模式匹配switch
语句中,对显式类型使用case
询问所讨论的值是该特定类型还是派生类型。它完全等同于is
switch (someString) {
case string s:
}
if (someString is string)
值null
没有类型,因此不满足上述任一条件。在这两个例子中,someString
的静态类型都不起作用。
模式匹配中的var
类型虽然起着通配符的作用,它将匹配任何值,包括null
。
这里的默认情况是死代码。
case var o
将匹配任何值,无论是空值还是非空值。非默认案例总是胜过默认案例,因此default
永远不会被击中。如果你看一下IL,你会发现它甚至没有被释放出来。
乍一看,这似乎很奇怪,它在没有任何警告的情况下编译(绝对让我大吃一惊)。但是这与可以追溯到1.0的C#行为相匹配。编译器允许默认情况,即使它可以简单地证明它永远不会被命中。以下面为例:
bool b = ...;
switch (b) {
case true: ...
case false: ...
default: ...
}
在这里,
default
将永远不会被命中(即使对于值不是1或0的bool
)。然而,C#从1.0开始就在没有警告的情况下允许这样做。模式匹配正符合这种行为。
问题内容: 我在JTextPane / JTextField(或它们下方的字体渲染中的某个地方)中发现了一个奇怪的错误。我想知道是否有人遇到过这种情况,并且可能对此有解决方案。 我试图在JTextPane中显示一些“特殊”或稀有字符,并且一旦更改JTextField的字体(与JTextPane完全无关!),JTextPane就会“分手”,不再显示这些字符字符。 这应该可以更好地解释我的意思: 编辑
我有以下代码来解析一个JSON文件: 要处理以下JSON文件: 如果我执行此代码,我将收到以下错误: 所以我开始一步一步地调试应用程序,看看part processing()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。 更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。 我不知道println方
问题内容: 我看到了我认为是错误的行为。@InjectMocks似乎并没有在每种测试方法之前创建一个新的测试主题。就像@Mock一样。在下面的示例中,如果Subject.section是最后一个,则@Test失败。如果不是最后两个都通过。我当前的解决方法是使用@BeforeClass,但这并不理想。 Subject.java: Section.java: SubjectTest.java 干杯。
问题内容: 我在GregorianCalendar类中遇到一个奇怪的行为,我想知道我是否真的做得不好。 仅当初始化日期的月份的实际Maximum大于我将日历设置为的月份时,才追加此值。 这是示例代码: 我知道问题是由于日历初始化日期是31天(可能是5月),与设置为2月(28天)的月份混淆了。修复很容易(只需在设置年和月之前将day_of_month设置为1),但是我想知道这确实是想要的行为。有什么
问题内容: 我正在为一个问题而苦苦挣扎,我不明白为什么它不起作用。如何通过将变量传递并转换为? 为什么在顶部代码段中不起作用,但在行下方的底部代码段中起作用? 唯一的区别似乎是添加了一个额外的变量,该变量也被键入为? 问题答案: 该是一种原始类型,同时是一个普通的Java类。您不能在原始类型上调用方法。但是该方法在上可用,如javadoc中所示 有关这些原始类型的更多信息,请参见此处
问题内容: 为什么的到哪里去了? 问题答案: 删除任何字符,并从字符串的开头和结尾。