在下面的代码中,我是try 访问s还是o并不重要,在这两种情况下,编译器都会报告变量没有初始化.我希望至少o始终被初始化,因为它是最不特定的类型.那么,为什么编译器甚至允许我在该场景中指定变量呢?

void Foo(object obj)
{       
        switch (obj)
        {
            case string s:
            case object o:
                Console.WriteLine(s);
                break;
        }      
}
        

我用的是.NET 7.

推荐答案

docs(重点是我的):

Switch语句执行first switch section whose case pattern matchesa匹配表达式中的语句列表,并且其case Guard(如果存在)的计算结果为真

所以我认为这是意料之中的事.你有两条通向Console.WriteLine的路径,其中一条或另一条匹配(而不是两条).在伪代码中,它可能看起来像这样:

string s;
object o;

if(obj is string)
{
   s = (string) obj;
   goto doSomething;
}


if(obj is object)
{
   o = (object) obj;
   goto doSomething;
}

doSomething:
// your Console.WriteLine here
// Console.WriteLine(s); Local variable 's' might not be initialized before accessing
// Console.WriteLine(o); Local variable 'o' might not be initialized before accessing

因此,如果第一个匹配,则第二个不会被处理(因为说明书说没有理由这样做),导致o不被初始化,如果第二个匹配,则意味着第一个不匹配,因此s不被初始化.

specification:

一个switch语句执行如下:

  • ...
  • Control is transferred according to the value of the converted switch expression:
    • 同一switch语句中case个标签的集合中的The lexically first pattern个标签,如果匹配Switch表达式的值,并且其防护表达式不存在或求值为真,则导致将控制转移到匹配的case个标签之后的语句列表.
  • ...

至于"为什么编译器甚至允许我在那个场景中指定变量?"--因为在我看来,规范并不禁止这样做:

每个switch_section由一个或多个switch_labels后跟statement_list组成(第13.3.2节).每个包含事例的switch_label具有相关联的模式(§11),对照该模式(§11)测试切换表达式的值.

因此,无论switch 部分中存在多少switch 标签,包括declaration one在内的所有图案都是允许的.

Csharp相关问答推荐

当MD5被废弃时,如何在Blazor WASM中使用它?

AutoMapper -如何为两个不同的用例设置单个映射?

Microsoft. SQLServer. Types(106.1000.6)在try 从用户定义的类型检索值时引发异常

将委托传递到serviceccollection c#web API

System. InvalidOperationException:无法将数据库中的字符串值i转换为映射的ItemType枚举中的任何值''''

在. net毛伊岛窗口的深度链接已经创建""

需要澄清C#的Clean Architecture解决方案模板的AuditableEntityInterceptor类

Blazor Foreach仅渲染最后一种 colored颜色

Int和uint相乘得到LONG?

如何将不同类型的扩展参数的javascript函数转换成C#风格?

使用可信第三方的Iext8.Net pdf签名

共享暂存/生产环境中Azure事件中心的建议配置

集合表达式没有目标类型

在C#中,非静态接口方法的抽象和虚拟是冗余的吗?

在C#中过滤Excel文件

具有类型识别的泛型方法

为什么我的伺服电机不动,下面的代码?

C#LINQ子字符串

如何将 colored颜色 转换为KnownColor名称?

使用Try-Catch-Finally为API端点处理代码--有什么缺点?