C#using语句可以在没有大括号的情况下编写吗?
我今天浏览了同事的c代码,发现如下:C#using语句可以在没有大括号的情况下编写吗?,c#,using-statement,C#,Using Statement,我今天浏览了同事的c代码,发现如下: using (MemoryStream data1 = new MemoryStream()) using (MemoryStream data2 = new MemoryStream()) { // Lots of code.......... } 我总是看到使用语句,后面是一对花括号,定义了对象生命的范围。编写代码的同事说,不需要使用data1using语句的花括号,代码做的事情与使用语句嵌套data2
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中:“Ausing
using(ResourceType r1=e1,r2=e2,…,rN=eN)形式的语句语句
完全等同于一系列嵌套的using
语句:using(ResourceType r1=e1)using(ResourceType r2=e2)…using(ResourceType rN=eN)语句我将其重构为一个新方法,该方法返回一次性对象。当然,这会导致运行时错误。如果大括号在那里,那么它将清楚地指示变量的范围,并警告它不是一个简单的重构。