C# 这个看似未连接的块(在if语句之后)是如何工作的?

C# 这个看似未连接的块(在if语句之后)是如何工作的?,c#,C#,我继承了一些代码,这些代码偶尔使用以下if表示法: if (a) foo(); { if (b) boo(); moo(); } 我不知道如何自然地阅读,但代码可以编译并运行 有人能解释一下它是如何工作的,这样我就可以用更容易理解的格式重写它了吗?或者,有人能解释一下为什么这个符号会有用吗?您发布的代码最好写为: if (a) { foo(); } if (b) { boo(); }

我继承了一些代码,这些代码偶尔使用以下if表示法:

if (a)
    foo();
{
    if (b)
        boo();
    moo();
}
我不知道如何自然地阅读,但代码可以编译并运行


有人能解释一下它是如何工作的,这样我就可以用更容易理解的格式重写它了吗?或者,有人能解释一下为什么这个符号会有用吗?

您发布的代码最好写为:

   if (a)
   {
       foo();
   }
   if (b)
   {
       boo();
   }
   moo();
C#中的大括号有两个用途:

  • 它们为变量声明创建一个作用域
  • 它们将语句组合在一起,以便条件语句和循环语句可以一次应用于多个语句
  • 无论是谁编写了你发布的代码,都选择不将其用于第二个目的
    if
    语句在不使用大括号的情况下是完全合法的,但它们只适用于紧跟其后的语句(如在第一个
    if
    之后调用
    foo()

    因为有一个与控制流无关的大括号的合法用例,但是,将大括号放在与
    if
    语句无关的随机位置是完全可以接受的

    此代码:

    foo();
    {
       var a = boo();
    }
    {
       var a = moo();
    }
    
    。。。等同于此代码:

    foo();
    var a = boo();
    var b = moo();
    
    。。。但是您会注意到,我无法命名第二个变量
    a
    ,因为它不再通过大括号与第一个变量分开

    或者,有人能解释一下为什么这个符号会有用吗

    我可以想到三种可能性:

  • 他们希望在方法的不同部分重用变量名,所以他们用大括号创建了一个新的变量范围
  • 他们认为大括号可能是一个很好的视觉辅助工具,可以封装里面的所有逻辑
  • 他们实际上很困惑,而且这个程序并不像他们想象的那样工作
  • 前两种可能性假设他们实际上做的不仅仅是在实际生产代码中调用
    foo()
    moo()


    无论如何,我认为这些可能性都不是编写这样代码的好理由,你完全有权以更容易理解的方式重写代码。

    花括号从
    foo()
    开始,而不是
    if(a)
    (比如
    if(a){
    )因此,在这种情况下,这些大括号是无用的

    if (a)
        foo();
    //{
        if (b)
            boo();
        moo();
    //}
    
    这等于

    if (a)
        foo();
    
    if (b)
        boo();
    
    moo();
    

    像这样的大括号用于限制上下文。在这些大括号内创建的变量只会存在到大括号结束。

    if(a)foo();if(b)boo();moo()
    至于你的最后一句话-我想不出这个符号有用的任何原因。你确定你没有忘记你继承的代码中的
    或者
    吗?语法是完全正确的,但是意图不是。值得检查这段代码的版本控制历史,看看是
    如果
    还是
    else
    在某个时刻出现。您甚至可能会收到一条提交消息,指明它更改的原因。或者是因为以前有一条if语句,有人删除了它,但没有删除大括号(可能是他们注释掉了它,然后删除了注释掉的行)我不认为最后两段代码是等价的,第一段代码既不在范围内保留
    a
    也不在范围内保留
    b
    ,第二段代码两者都保留。实际等价的代码是
    foo();boo();moo()第四种选择是减少内存占用。这在保留堆栈和堆空间的递归方法中特别有用,因为变量只有在超出范围且没有剩余引用时才可用于垃圾收集。但是,如果这是一个问题,可能会有一些问题事实上,我最近重新阅读了乔尔SpOLSKY自己关于这个主题的有趣文章:它也解决了这种情况。我认为这是一个代码的气味和第二个重写。对于一个例子,@ PM100谈论,读线程的问题,线程也可以帮助我。f您不熟悉所谓的显式局部作用域,即在方法体(访问器、构造函数等)内“无动机”使用
    {…}