web-dev-qa-db-ja.com

C#usingステートメントは中括弧なしで記述できますか?

今日、同僚のc#コードを閲覧していて、次のことがわかりました。

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

私はいつもusingステートメントの後に、オブジェクトの寿命の範囲を定義する1組の中括弧が続くのを見てきました。コードを書いた私の同僚は、data1usingステートメントの中括弧は不要であり、コードはそれらが存在し、data2usingステートメントをネストした場合と同じことをしたと言いました。では、中括弧を省略するとどうなりますか?

45
DaveB

はい、次のステートメントを使用してそれらを1つにまとめることもできます。

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

forまたはifステートメントで中括弧を省略した場合も、同じ規則が適用されます。

ちなみに、コンパイルされたコードに反映すると、 コンパイラ 逆コンパイラは中括弧を追加します。

19
Chuck Conway

まさに彼が言ったこと。上記のコードは、次のように書くのとまったく同じです。

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

ステートメント内にコマンドが1つしかない限り、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();
}
17
Stephen

これは実行可能ですがリスクがあります。誰かが後で他のことが起こる前にdata1に何かをしたいと決めた場合、data1の使用直後に配置する可能性があり、data2の使用範囲全体から外れる可能性があります。これはコンパイルを中断する可能性がありますが、それでもリスクが高く無意味な構文ショートカットです。

4
Jimmy Hoffa

同僚が言ったこととまったく同じです。これは、ステートメントをネストするのと同じです。 data2のdisposeは、data1のdispose関数の直前に呼び出されます。

3
fletcher

人々が言っ​​ているように:ステートメントの後に1行しかない場合、中括弧なしで機能します。しかし、人々は彼らの例で、その1行がそれ自身のカールした中括弧でif/using/forになる可能性があることを示すことを怠っています。次に例を示します。

if(foo)
  if(bar)
  {
     doStuff();
  }
1
TheHitchenator

C#8から、中括弧なしでこの構文を使用することもできます。

using var foo = new Foo();
var bar = foo.Bar();

fooは、スコープの最後(通常はメソッドの最後)に配置されます。したがって、いつどこで使用するかに注意してください。

参照- https://docs.Microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement#example

0
JvR