なぜC#は許可しないこの文のないコードブロック(例えばif
、else
、for
、while
)?
void Main()
{
{ // any sense in this?
Console.Write("foo");
}
}
なぜC#は許可しないこの文のないコードブロック(例えばif
、else
、for
、while
)?
void Main()
{
{ // any sense in this?
Console.Write("foo");
}
}
回答:
あなたが与える文脈では、意味はありません。コンソールに定数文字列を書き込むと、プログラムフローのどこでも同じように機能します。1
代わりに、通常はそれらを使用して、一部のローカル変数のスコープを制限します。これはこことここでさらに詳しく説明されています。見てくださいジョアン・アンジェロの答えとクリス・ウォリスの答えの簡単な例について。同じことがCスタイルの構文を持つ他のいくつかの言語にも当てはまると思いますが、それらがこの質問に関連するというわけではありません。
1 もちろん、まったく予想外のことConsole
をするWrite()
メソッドを使って、面白くして独自のクラスを作成しようと決心しない限り。
out
記述されたインターフェイス実装にパラメーターとして渡すことである場合、混合言語プロジェクトで観察できます。別の言語で、その実装は変数を書き込む前に変数を読み取ります。
に{ ... }
は、少なくともローカル変数に新しいスコープを導入するという副作用があります。
私はswitch
ステートメントでそれらを使用して、ケースごとに異なるスコープを提供する傾向があります。このようにして、使用する最も近い場所で同じ名前のローカル変数を定義し、ケースレベルでのみ有効であることを示すことができます。
{}
お越しの方金バッジを保つために:) ...
これは、中括弧を使用してスコープを定義する多くのC構文言語の論理的な副作用であるため、C#の機能ではありません。。
あなたの例では、中括弧はまったく効果がありませんが、次のコードでは、中括弧は変数のスコープ、したがって可視性を定義します。
これは、iが最初のブロックでスコープから外れ、次のブロックで再度定義されるために許可されます。
{
{
int i = 0;
}
{
int i = 0;
}
}
iがスコープから外れ、外側のスコープに表示されなくなったため、これは許可されていません。
{
{
int i = 0;
}
i = 1;
}
などなど。
{}
括弧として知られていますか?
One of two marks of the form [ ] or ( ), and in mathematical use also {}, used for enclosing a word or number of words, a portion of a mathematical formula, or the like, so as to separate it from the context;
。いずれの場合も括弧ではありませんが、「中括弧」は問題ないようです。
私が検討します {}
は、いくつかのステートメントを含むことができるステートメントます。
ブール式の後に1つのステートメントが続くifステートメントについて考えてみます。これはうまくいくでしょう:
if (true) Console.Write("FooBar");
これも機能します:
if (true)
{
Console.Write("Foo");
Console.Write("Bar");
}
私が間違っていなければ、これはブロックステートメントと呼ばれます。
{}
他のステートメントを含めることができるため、他のを含めることもできます{}
。変数のスコープは、その親{}
(ブロックステートメント)によって定義されます。
私が言いたいのは、それ{}
は単なるステートメントなので、ifなどを必要としないということです...
C構文言語の一般的な規則は、「その間のすべてを{ }
単一のステートメントとして扱う必要があり、単一のステートメントが可能なところならどこにでも移動できます」です。
if
。for
、while
またはdo
。すべての意図と目的のために、それは言語文法がこれを含んでいたようです:
<statement> :== <definition of valid statement> | "{" <statement-list> "}"
<statement-list> :== <statement> | <statement-list> <statement>
つまり、「ステートメントは、(さまざまなもの)または開始中括弧で構成され、その後にステートメントリスト(1つ以上のステートメントを含む場合があります)が続き、その後に閉じ中括弧が続きます」。IE「{ }
ブロックはどこでもどんなステートメントでも置き換えることができます」。コードの途中に含まれます。
{ }
単一のステートメントが移動できる場所にブロックを許可しないと、実際には言語定義がより複雑になります。
// if (a == b)
// if (a != b)
{
// do something
}
あなたは「なぜ」C#が前のステートメントなしでコードブロックを許可するのかと尋ねました。「なぜ」という質問は、「この構成の可能な利点は何でしょうか?」と解釈することもできます。
個人的には、コードブロックがローカル変数のスコープを制限することを念頭に置いて、他の開発者の可読性が大幅に向上するC#でステートメントのないコードブロックを使用しています。たとえば、次のコードスニペットについて考えてみます。これは、追加のコードブロックのおかげではるかに読みやすくなっています。
OrgUnit world = new OrgUnit() { Name = "World" };
{
OrgUnit europe = new OrgUnit() { Name = "Europe" };
world.SubUnits.Add(europe);
{
OrgUnit germany = new OrgUnit() { Name = "Germany" };
europe.SubUnits.Add(germany);
//...etc.
}
}
//...commit structure to DB here
これは、構造レベルごとにメソッドを使用することで、よりエレガントに解決できることを認識しています。ただし、繰り返しになりますが、サンプルデータシーダーのようなものは通常迅速である必要があることに注意してください。
したがって、上記のコードは線形に実行されますが、コード構造はオブジェクトの「実際の」構造を表しているため、他の開発者が理解、維持、拡張するのが容易になります。