代码之家  ›  专栏  ›  技术社区  ›  Arseni Mourzenko

用大括号表示变量范围是错误的吗?

  •  17
  • Arseni Mourzenko  · 技术社区  · 14 年前

    我有时使用大括号来隔离代码块,以避免以后错误地使用变量。例如,当我把几个 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();
    }
    

    现在,每当一个块跟随一个空行时,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
    }
    

    所以,

    1. 使用大括号创建代码块只是为了变量作用域?

    2. 如果可以的话,如何在不违反StyleCop规则的情况下让它更具可读性?

    5 回复  |  直到 14 年前
        1
  •  7
  •   Mac Umer    14 年前

    我不认为仅仅用大括号来限定范围有什么错——有时它会非常有用。

    举个例子-我曾经遇到过一个使用 Profile 对象到代码的时间段。它们是通过测量从创建到销毁的时间来工作的,因此在堆栈上创建,然后在超出范围时销毁,从而测量在特定范围内花费的时间,效果最好。如果你想计时一些本来就没有自己作用域的东西,那么添加额外的大括号来定义这个作用域可能是最好的方法。

        2
  •  23
  •   Adam Robinson    14 年前

    没什么不对的 本身

    如果要复制和粘贴代码,很可能需要重构代码并生成重复调用的函数,而不是重复执行类似但不同的代码块。

        3
  •  13
  •   Stephen Cleary    14 年前

    使用 using 语句而不是空的大括号块。

    从更大的角度来看,您应该考虑将此方法拆分为更小的方法。使用一个 SqlCommand SqlCommand命令 .

        4
  •  5
  •   STO    14 年前

    我觉得这样的积木是个好主意,我经常用它们。当您需要分离太小而无法提取到方法中的代码块时,或者当方法由几个代码块组成时,它非常有用 看起来像 但逻辑不同。它允许赋予变量相同的名称,而不存在命名冲突,这使得方法体更具可读性。

    顺便说一句,我认为StyleCop的默认规则集有更多的规则,权宜之计值得商榷。

        5
  •  3
  •   user1228 user1228    14 年前

    我不得不说,如果我在你之后再写这段代码,我会对你使用scope有点反感。恐怕这不是惯例。

    我认为你这样做是一种气味。我认为更好的做法是用完全描述性的名称和文档将每个作用域分割成自己的方法。