花括号块是正确的C#语法吗?它有什么作用吗?

3

我正在阅读别人的代码,看到了很多这样的实例。我提供一小段代码。它是一个库函数,用于包装nHibernate。我感到困惑的是在会话(session)被创建后的第五行。

public T GetById<T>(string id) where T : BaseObject
{
     T retObj = null;
     ISession session = EnsureCurrentSession();
     {
          retObj = session.Get<T>(id);
     }

     return retObj;
}

乍一看,我以为这是使用语句的示例,但实际上并不是。据我所见,花括号似乎可以没有。在那里设置一个块的唯一实际目的是在内部创建变量,并将它们的范围限制在该块内,但这里并没有发生。或者我错过了什么?

3
我认为这只是一种奇怪的编码风格... - NoviceProgrammer
7个回答

6
这段代码看起来像是一个未完成的编辑,虽然代码合法但仍有些奇怪。
针对你的说法,可以补充一下:
设置代码块的唯一实际目的是在其中创建变量,使其作用域被限定在该块内。
这是创建代码块的一个实际目的,但并不是唯一的目的。例如:
class C
{
    public int x;
    void M()
    {
        x = 123;
        if (whatever)
        {
            int x = q;
        }
    }
}

这段代码不合法,因为在首次使用变量名称x的代码块中,其简单名称x的使用不一致。一开始,x指代的是this.x,但后来却指代了一个局部变量。在C#中,这是不合法的;在C#中,一个名称在其首次使用的代码块中只能表示一件事情

你可以通过以下方式“修复”这个问题...

class C
{
    public int x;
    void M()
    {
        {
           x = 123;
        }
        if (whatever)
        {
            int x = q;
        }
    }
}

现在,两个用同一名称表示不同含义的块没有任何重叠部分。但这是解决问题的愚蠢方式。更好的方法是重命名本地变量


3

在这种情况下,它不起任何作用。实际上,它可能是一个using块的剩余部分,也就是说,在以前的版本中代码可能看起来像这样:

using (ISession session = EnsureCurrentSession())
{
   retObj = session.Get<T>(id);
}

目前,我会审查EnsureCurrentSession的实现方式。可能需要加上using,或者如果不需要,就删除大括号。


是的,我认为这是正确的。我们的代码库中确实有完全像这样(带有“using”)的代码。我可以想象有人想要删除“using”,但懒得同时删除大括号。 - svick

3
这里的花括号是多余的,不过你是正确的,你可以创建花括号以便在该块的作用域内创建变量。但是这种模式很少被使用。

1

实际上,新语句后面的大括号是用来在类中初始化变量的。这个主题在另一篇帖子中已经讨论过了。


1

我认为您没有漏掉任何东西 - 在这种情况下大括号不起作用。


0

没有遗漏任何东西。它们是多余的,而且坦率地说,留下这样的代码很糟糕。但是当代码确实需要本地作用域/使用时,可能已经被更改/添加为习惯。


0

我的最佳猜测是,曾经有一个 if (session != null)。然后进行了代码审查,指出这个测试是不必要的,因为 EnsureCurrentSession() 永远不会返回 null,如果会话不是当前会话,则会抛出一个 Exception


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接