今日、同僚のc#コードを閲覧していて、次のことがわかりました。
using (MemoryStream data1 = new MemoryStream())
using (MemoryStream data2 = new MemoryStream())
{
// Lots of code..........
}
私はいつもusing
ステートメントの後に、オブジェクトの寿命の範囲を定義する1組の中括弧が続くのを見てきました。コードを書いた私の同僚は、data1
using
ステートメントの中括弧は不要であり、コードはそれらが存在し、data2
using
ステートメントをネストした場合と同じことをしたと言いました。では、中括弧を省略するとどうなりますか?
はい、次のステートメントを使用してそれらを1つにまとめることもできます。
using (MemoryStream data1 = new MemoryStream(),
data2 = new MemoryStream())
{
// do stuff
}
for
またはif
ステートメントで中括弧を省略した場合も、同じ規則が適用されます。
ちなみに、コンパイルされたコードに反映すると、 コンパイラ 逆コンパイラは中括弧を追加します。
まさに彼が言ったこと。上記のコードは、次のように書くのとまったく同じです。
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();
}
これは実行可能ですがリスクがあります。誰かが後で他のことが起こる前にdata1に何かをしたいと決めた場合、data1の使用直後に配置する可能性があり、data2の使用範囲全体から外れる可能性があります。これはコンパイルを中断する可能性がありますが、それでもリスクが高く無意味な構文ショートカットです。
同僚が言ったこととまったく同じです。これは、ステートメントをネストするのと同じです。 data2
のdisposeは、data1
のdispose関数の直前に呼び出されます。
人々が言っているように:ステートメントの後に1行しかない場合、中括弧なしで機能します。しかし、人々は彼らの例で、その1行がそれ自身のカールした中括弧でif/using/forになる可能性があることを示すことを怠っています。次に例を示します。
if(foo)
if(bar)
{
doStuff();
}
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