C# 如果没有大括号,using语句有什么作用域

C# 如果没有大括号,using语句有什么作用域,c#,ado.net,using-statement,C#,Ado.net,Using Statement,我继承了以下代码: using (var dataAccessConnection = da.GetConnection()) //no opening curly brace here using (var command = new SqlCommand(sql, dataAccessConnection.Connection)) { command.CommandType = CommandType.Text; using (var

我继承了以下代码:

    using (var dataAccessConnection = da.GetConnection()) //no opening curly brace here
    using (var command = new SqlCommand(sql, dataAccessConnection.Connection))
    {
        command.CommandType = CommandType.Text;
        using (var sqlDataReader = command.ExecuteReader(CommandBehavior.CloseConnection))
        {
            while (sqlDataReader.Read())
            {
                rueckgabe.Add(new Myclass
                                  {
                                      Uid = Guid.NewGuid(),
                                      ImportVersionUid = versionUid,
                                      MyProperty = Convert.ToInt32(sqlDataReader["MyProperty"])
                                        });       
            }
        }
        command.Connection.Close();
        dataAccessConnection.Connection.Close();
    }
查看代码,我在using子句之后扩展了一个大括号

代码编译并执行预期的操作。应用程序的行为不可预测。有时它无法访问数据库服务器


这个代码有意义吗?dataAccessConnection是否具有rigth作用域?

使用不带显式大括号的
语句仅适用于以下语句

using (Idisp1)
    // use it

// it's disposed
using (Idisp1)
    using (Idisp2)
    {

    }
因此,当使用链条时,它们的工作方式相同。第二个
在这里用作一条语句

using (Idisp1)
    // use it

// it's disposed
using (Idisp1)
    using (Idisp2)
    {

    }
Commenter stakx建议使用格式化来明确编译器如何使用块读取数据。实际上,这些文件通常会被格式化为遇到的OP:

using (Idisp1)
using (Idisp2)
{

}
这相当于:

using (Idisp1)
{
    using (Idisp2)
    {

    }
}
请注意,顶部的第一个始终是要处理的最后一个。因此,在前面的所有示例中,
Idisp2.Dispose()
Idisp1.Dispose()
之前调用。这在很多情况下都是不相关的,您可能会做类似的事情,但是我相信您应该始终知道您的代码将要做什么,并做出明智的决定,不要在意

阅读网页时就是一个例子:

HttpWebRequest req = ...;

using (var resp = req.GetResponse())
using (var stream = resp.GetResponseStream())
using (var reader = new StreamReader(stream))
{
    TextBox1.Text = reader.ReadToEnd(); // or whatever
}
我们获取响应,获取流,获取读取器,读取流,处理读取器,处理流,最后处理响应

请注意,正如评论员Nikhil Agrawal所指出的,这是一种关于块的语言特性,它不特定于使用
关键字的
。例如,如果
块:

if (condition)
    // may or may not execute

// definitely will execute

if (condition1)
    if (condition2)
       // will execute if both are true

// definitely will execute
当然,尽管你永远不应该这样使用
if
语句,因为读起来很糟糕,但我认为这有助于你理解
使用
的情况。我个人非常喜欢使用块链接

C语言规范()将使用
语句的
描述为:

使用语句:

使用(
资源获取
嵌入式语句

即:

using
语句获取一个或多个资源,执行语句,然后处置资源

我的重点

那么,我们最终如何将其与花括号一起使用呢?因为嵌入式语句的定义是:

嵌入语句:


空语句
表达式语句
选择语句
迭代语句
跳转语句
try语句
选中的语句
未选中的语句
锁定语句
使用语句
收益率报表

以及:

嵌入语句nonterminal用于出现在其他语句中的语句

最后,我们发现块的定义如下:

块允许在允许单个语句的上下文中编写多个语句

区块:

{
语句列表opt
}

所以基本上,花括号总是可以用来表示一条语句被接受的情况,而不是有多条语句

碰巧的是,我们几乎总是希望使用多个语句,因此大括号往往被视为
if
using
等语句的一部分。然而,事实上,它们是语言的一个独立部分。

从C#8.0开始,
using
关键字可以用作一次性对象的变量声明中的属性()。语义正如您所期望的——对象在作用域的末尾自动释放

        public class Disposable : IDisposable
        {
            string name;

            public Disposable(string name)
            {
                this.name = name;
            }

            public void Dispose()
            {
                Console.WriteLine(name + " disposed");
            }

            public void Identify()
            {
                Console.WriteLine(name);
            }

            static void Main(string[] args)
            {
                using Disposable d1 = new Disposable("Using 1");
                Disposable d2 = new Disposable("No Using 2");
                using Disposable d3 = new Disposable("Using 3");
                Disposable d4 = new Disposable("No Using 4");
                d1.Identify();
                d2.Identify();
                d3.Identify();
                d4.Identify();
            }
        }
输出

Using 1 No Using 2 Using 3 No Using 4 Using 3 disposed Using 1 disposed 使用1 禁止使用2 使用3 禁止使用4 使用3 使用1
该链接上的一位评论员说,“看起来第一个using语句是空的,没有使用过。”。这就是发生在我身上的事。但我现在明白了,它实际上是一种干净的风格,“使用”就像“如果”一样有效。即使我个人使用大括号,如果一个元素更准确地跟随,它也可以不使用大括号,我会说它们适用于以下语句(正如你所观察到的,它实际上可能会跨越多行)@Damien_,不信者对!这就是我要找的词。我将编辑我的答案。谢谢。@MatthewHaugen:您可以添加:此块行为是用语言实现的,不是特定于使用的。@MatthewHaugen-自C#8.0以来,情况发生了变化,对吗?@Homer是和否-情况确实得到了添加,但我在这里说的仍然是真的。“简单使用语句”没有paren。因此
使用(var resp=req.GetResponse())
仍然只保留下一行的作用域,但是
使用var resp=req.GetResponse()
将一直持续到块的末尾。下次有机会我会编辑的。所以,也许我遗漏了什么,但这有什么意义呢?在函数/方法中声明变量和使用此方法是否会产生相同的结果?我认为将静态
Main
方法移到类
Disposable
之外会使示例更容易理解。