Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#using语句可以在没有大括号的情况下编写吗?_C#_Using Statement - Fatal编程技术网

C#using语句可以在没有大括号的情况下编写吗?

C#using语句可以在没有大括号的情况下编写吗?,c#,using-statement,C#,Using Statement,我今天浏览了同事的c代码,发现如下: using (MemoryStream data1 = new MemoryStream()) using (MemoryStream data2 = new MemoryStream()) { // Lots of code.......... } 我总是看到使用语句,后面是一对花括号,定义了对象生命的范围。编写代码的同事说,不需要使用data1using语句的花括号,代码做的事情与使用语句嵌套data2

我今天浏览了同事的c代码,发现如下:

    using (MemoryStream data1 = new MemoryStream())
    using (MemoryStream data2 = new MemoryStream())
    {
        // Lots of code..........
     }

我总是看到
使用
语句,后面是一对花括号,定义了对象生命的范围。编写代码的同事说,不需要使用
data1
using
语句的花括号,代码做的事情与使用
语句嵌套
data2
语句的情况相同。那么,当使用大括号时会发生什么呢?

for
if
语句中省略大括号时,同样的规则也适用


顺便说一句,如果您在编译后的代码中进行反思,编译器反编译器会添加大括号。

正如您的同事所说,这相当于嵌套语句。
data2的dispose将在
data1的dispose函数之前立即调用,如果语句后面只有一条指令,则不需要大括号。这与
if
语句类似

if(true)
{
   Console.Writeline("hello")
}
意思是一样的

if(true)
   Console.Writeline("hello")

正是他说的。上面的代码与编写代码完全相同:

using (MemoryStream data1 = new MemoryStream()) 
{
    using (MemoryStream data2 = new MemoryStream())
    {
        // Lots of code
    }
}
只要if/else/for/while/using/etc语句中只有一个命令,就可以省略if/else/for/while/using/etc语句后面的大括号。示例:

// Equivalent!
if (x==6) 
    str = "x is 6";

if(x == 6) {
    str = "x is 6";
}

// Equivalent!
for (int x = 0; x < 10; ++x) z.doStuff();

for (int x = 0; x < 10; ++x) {
    z.doStuff();
}

// NOT Equivalent! (The first one ONLY wraps the p = "bob";!)
if (x == 5) 
p = "bob";
z.doStuff();

if (x == 5) {
   p = "bob";
   z.doStuff();
}
//等价物!
如果(x==6)
str=“x是6”;
如果(x==6){
str=“x是6”;
}
//等价物!
对于(intx=0;x<10;++x)z.doStuff();
对于(int x=0;x<10;++x){
z、 doStuff();
}
//不相等!(第一个仅包装p=“bob”!)
如果(x==5)
p=“鲍勃”;
z、 doStuff();
如果(x==5){
p=“鲍勃”;
z、 doStuff();
}

是的,您也可以将它们放在一个using语句中:

using (MemoryStream data1 = new MemoryStream(), 
                    data2 = new MemoryStream())
{
    // do stuff
}

这是可行的,但也有风险,因为如果有人后来决定在data1发生其他事情之前对其执行某些操作,他们可能会在data1使用后立即将其放置,这将使其超出data2的整个使用范围。这可能会破坏编译,但仍然是一个危险的、毫无意义的语法快捷方式。

正如人们所说:如果语句后面只有一行,那么在没有大括号的情况下,它就可以工作。然而,人们忽略了在他们的例子中显示一行可以是if/using/for,并带有自己的大括号。以下是一个例子:

if(foo)
  if(bar)
  {
     doStuff();
  }
在C#8中,您也可以在不使用大括号的情况下使用此语法:

使用var foo=new foo();
var bar=foo.bar();
foo
将在其作用域的末尾进行处理(通常在方法的末尾)——因此请注意何时何地使用


参考-

一个区别是,当嵌套
语句时,我们会缩进内部语句,但是使用
语句嵌套的
语句通常是左对齐的。这是一个常见的惯例,当然不是语言语法。+1,吹毛求疵的一点:编译器实际上并没有添加大括号,反编译器将它们放入其中。@JaredPar感谢您的澄清。我不知道。我正要发帖,但杰雷德帕抢先发了过来+1.他和答案。只要我的2美分——正如答案所示,你“可以”这样做,但我认为,出于可读性的目的,你不应该这样做。对我来说,这就像将if/else/while/lock/etc.块用大括号括起来一样——即使它们不是必需的,也更容易阅读。在我看来,使用
语句堆叠的
要比使用
语句嵌套的
可读性强得多。特别是在将3-4个Streams/StreamReader链接在一起以执行单个操作集的情况下。@Joel:可能与其他操作一样,应该考虑具体情况。如果只是两个,我的意见是绝对用括号把它们套起来。如果我们像你说的那样谈论4,也许堆叠是更好的方法。但是,在创建data2之前第一次需要访问data1时,这意味着要更改代码的可读性,而不是仅仅添加一行代码。@Joe:这很公平。根据我的经验,我对涉及
使用
块的事情的使用往往是一成不变的。我不认为我曾经有机会在使用“< /Cord>”语句的情况下在两个堆叠的<>代码之间插入一些逻辑,而且一旦编写出来,我就不必以任何方式修改它们。但是我们的工作仍然是让代码尽可能地被其他人维护,以免其他人在我们的代码中加入bug。我很确定,在某些情况下,这种构造的行为是不同的。我现在不记得确切的原因,但我相信我在Bill Wagners的一本书中读到过。请注意,如果多个对象的类型相同,则只能使用
语句将多个对象放入一个
MemoryStream
在这种情况下。@FearofahackPlanet:根据C#spec,行为没有区别。@fletcher:它们的处理顺序与标准嵌套的
using
语句完全相同。从C#spec中:“A
using
using(ResourceType r1=e1,r2=e2,…,rN=eN)形式的语句语句
完全等同于一系列嵌套的
using
语句:
using(ResourceType r1=e1)using(ResourceType r2=e2)…using(ResourceType rN=eN)语句我将其重构为一个新方法,该方法返回一次性对象。当然,这会导致运行时错误。如果大括号在那里,那么它将清楚地指示变量的范围,并警告它不是一个简单的重构。