为可变范围目的使用大括号是错误的吗?

Ars*_*nko 19 c# scope coding-style stylecop object-lifetime

我有时会使用大括号来隔离代码块,以避免以后错误地使用变量.例如,当我SqlCommand在同一个方法中放入几个s时,我经常复制粘贴代码块,最后混合名称并执行两次命令.添加大括号有助于避免这种情况,因为SqlCommand在错误的位置使用错误将导致错误.这是一个例子:

Collection<string> existingCategories = new Collection<string>();

// Here a beginning of a block
{
    SqlCommand getCategories = new SqlCommand("select Title from Movie.Category where SourceId = @sourceId", sqlConnection, sqlTransaction);
    getCategories.Parameters.AddWithValue("@sourceId", sourceId);
    using (SqlDataReader categoriesReader = getCategories.ExecuteReader(System.Data.CommandBehavior.SingleResult))
    {
        while (categoriesReader.Read())
        {
            existingCategories.Add(categoriesReader["Title"].ToString());
        }
    }
}

if (!existingCategories.Contains(newCategory))
{
    SqlCommand addCategory = new SqlCommand("insert into Movie.Category (SourceId, Title) values (@sourceId, @title)", sqlConnection, sqlTransaction);

    // Now try to make a mistake and write/copy-paste getCategories instead of addCategory. It will not compile.
    addCategory.Parameters.AddWithValue("@sourceId", sourceId);
    addCategory.Parameters.AddWithValue("@title", newCategory);
    addCategory.ExecuteNonQuery();
}
Run Code Online (Sandbox Code Playgroud)

现在,每当一个块跟随空行时,StyleCop就会显示一个警告.另一方面,不放空行会使代码更难理解.

// Something like:
Collection<string> existingCategories = new Collection<string>();
{
    // Code here
}

// can be understood as (is it easy to notice that semicolon is missing?):
Collection<string> existingCategories = new Collection<string>()
{
    // Code here
}
Run Code Online (Sandbox Code Playgroud)

所以,

  1. 使用大括号创建代码块只是出于可变范围目的,是否有问题

  2. 如果没问题,如何在不违反StyleCop规则的情况下使其更具可读性?

Ada*_*son 22

封锁代码本身并没有什么不妥,但你需要考虑为什么要这样做.

如果您正在复制和粘贴代码,则可能会出现这样的情况,即您应该重构代码并生成重复调用的函数,而不是重复执行类似但不同的代码块.

  • 我同意.技术上没有任何错误.这是一种风格上的抱怨,可能是一个长期功能的警示标志,应该分成更小,更易于管理的部分. (5认同)

Ste*_*ary 13

使用using语句而不是裸括号块.

这将避免警告,并使您的代码在资源方面更有效.

从更大的角度来看,您应该考虑将此方法拆分为更小的方法.使用一个SqlCommand后跟另一个通常可以通过调用一个方法然后调用另一个方法来完成.然后每种方法都使用自己的本地方法SqlCommand.

  • 我相信using()需要一个IDisposable,在这种情况下他可能没有. (11认同)
  • 我同意.将这些代码块转换为自己的方法并调用它们.作为OP的块有它们看起来有点奇怪,如果我遇到那些代码,我会重构它. (2认同)

Mac*_*Mac 7

我认为使用大括号纯粹是为了划分范围没有任何问题 - 它有时非常有用.

一个典型的例子 - 我曾经遇到过一个使用Profile对象来计算代码段时间的分析库.这些通过测量从创建到销毁的时间来工作,因此通过在堆栈上创建然后在超出范围时被销毁而最佳地工作,从而测量在该特定范围中花费的时间.如果你想要计算一些本身没有自己范围的东西,那么添加额外的大括号来定义这个范围可能是最好的方法.

至于可读性,我能理解为什么了StyleCop不喜欢它,但任何对C/C++/Java的/ C#的经验/ ...都知道,一个一对括号定义了一个范围,它应该是相当明显的是,那是什么你想要做的.


STO*_*STO 5

我认为这样的块是个好主意,我经常使用它们。当您需要分离太小而无法提取到方法中的代码块,或者当方法由很少的代码块组成看起来彼此相似但逻辑不相同的代码时,这很有用。它允许为变量赋予相同的名称而不会引起命名冲突,这使方法主体更具可读性。

顺便说一句,我认为StyleCop具有默认规则集,其中包含更多规则,权宜之计值得商bat。