请教个基础问题,关于switch的

中骑士 2022-08-15 10:19:19

 

看看代码,当i=2时,直接执行case 2了,但此时aArray应是未定义类型吧???未声明的实例竟然可以直接使用???

也许有人说case 1里声明了,那岂不是说,case1也执行了?

挺基础的问题,哪位大神受累解答一下?

...全文
113 7 打赏 收藏 举报
写回复
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
switch块就是有这毛病。我也不知道为何它就是一个case执行完,如果没有break语句,它还会继续往下执行。
  • 打赏
  • 举报
回复

一般情况下,变量声明确实是执行才赋值,这个 switch case 应该是特例,提前就把变量给声明了。
你可以用一个自定义类替代这个变量类型,让这个类初始化的时候往 console 写日志。
看下运行到哪一句的时候,这个自定义类被创建了。

我猜测这种原因有二:
⒈编译器并不是逐行执行的,而是一个块一个块执行的。
一个花括号就是一个语句块。
⒉C#编译器的特殊优化。
运行时(Runtime)会给语句块分配一个变量表,用于记录该“局部”的变量。
可惜我对 IL 中间语言也不是很懂,拿到底层代码一看就知道了

  • 打赏
  • 举报
回复

变量的范围是花括号,如果你把上面打个花括号看看。你看他还让你用不让你用
他不会让你用了,计算机么,不会骗人的。写规则的人写的是那个规则,他就按那个规则判定。
而C#那个写规则的人,认为变量范围是花括号的
比如下面的代码,他不让你用了把

int i = 2;

switch (i)
{
    case 1:
    {
        var a = 1;
        break;
    }
    case 2:
        a = 2;
        break;
}


好,你知道这个规则了。那么还有反例对吧。都说方法内不准重复定义变量对把。但是我们说规则么,如果我符合规则。你猜可以不可以重复定义呢??你会发现我们又可以重复定义变量了

{
    int i = 2;
}

{
        int i = 3;
}


  • 打赏
  • 举报
回复
@wanghui0380 这种东西呢,看上去好像没用 但其实还算比较有用,比如目前大量的委托,当委托闭包时候会有自由变量穿越问题。自由变量之所以是自由变量那是因为他在另外的作用域里,想防止他成为自由变量,就得利用这种花括号规则,把自由变量用个临时变量接一下放到本层同级的花括号里,这样他们就在相同作用域里。(变相约束作用域范围,防止他自由穿越)
  • 举报
回复 2

case 1 并没有执行。
aArray 只是在 case 1 中作了声明而已。
如下图可以看得非常清楚。

img

如果希望彻底避免这种情况,可以用 {} 加在 case 前后, 类似下面:
你看,下面的再引用就是直接出错了。

img

  • 打赏
  • 举报
回复 1
中骑士 08-15
@吉普赛的歌 非常感谢这位的解答。但是我还想问这个问题:“case1没有执行”那为什么case2可以使用未声明的变量?,反编译也看不懂。。。
  • 举报
回复
@中骑士 怎么可能没有声明呢?不声明,根本代码都写不下去,还没有编译就出错了。 如果不另外加 {} ,那这个 aArray 在 switch 之内是有效的。 所以,执行到 switch { 的时候,aArray 就已经声明了,只是没有赋值而已。 不过,有意思的是,如果 string aArray 写在 case 2, 则 case 1 是用不了的。
  • 举报
回复 1
发帖
C#

10.8w+

社区成员

.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
帖子事件
创建了帖子
2022-08-15 10:19
社区公告

让您成为最强悍的C#开发者