C#のif文の波括弧{}について

C#ではifなどの{}を省略1して書けます。たとえば

// これを
if (girl.IsBoyish)
{
    Console.Write("かわいいね");
}

// こう
if (girl.IsBoyish)
    Console.Write("かわいいね");

こんな感じで書ける訳ですね。タイプ量が減りますし個人的にはこのスタイルが好きです。

ただしあくまでifの後が単一の処理の場合なので、girl.IsBoyishtrueの場合は「(1)コンソール出力」と「(2)ボーイッシュリストに入れる」ということをしたい場合に

if (girl.IsBoyish)
    Console.Write("かわいいね");
    boyishGirls.Add(girl);

こういう風には書けません。C#はインデントをブロックとして解釈しないので、このコードは下記の様に解釈されます。

if (girl.IsBoyish)
{
    Console.Write("かわいいね");
}
boyishGirls.Add(girl);

この場合、「(1)コンソール出力」はgirl.IsBoyishtrueの場合のみですが、「(2)ボーイッシュリストに入れる」はgirl.IsBoyishfalseでも実行されてしまいます。

ボーイッシュリストにボーイッシュじゃない女の子が入っていると都合が悪いですよね?ね?

なので、正しくは

if (girl.IsBoyish)
{
    Console.Write("かわいいね");
    boyishGirls.Add(girl);
}

と書かなければなりません。

※実際にはif{}を省略して複数行書くと、boyishGirls.Add(girl);の行のインデントはIDEなどでは効かないので、ifの範囲外ということはすぐに分かると思います。

こういう事情があるので、ifelseが連続するような判定では{}を省略すると意図しない結果になる場合があります。たとえば次のようなケースをプログラムで表現するとします。

if (!girl.HasShortHair)
{
    if (girl.IsBokuGirl)
    {
        Console.Write("かわいいね");
    }
}
else
{
    Console.Write("かわいいね");
}

上記は「女の子がショートヘアでなく、かつボクっ娘である」または「女の子がショートヘアである」場合にコンソール出力をするというコードです。

※この条件判定は私の趣味ですが「ショートヘアでもボクっ娘でもない女の子は可愛くねぇ!」という主張ではありませんのでご承知おきください。

これを、{}を省略しようと思って下記のように書くとします。

if (!girl.HasShortHair)
    if (girl.IsBokuGirl)
        Console.Write("かわいいね");
else
    Console.Write("かわいいね");

一見{}を省けたように見えますが、前述の通りC#ではインデントはブロックとして解釈されません。つまり、上記のコードは下記のように解釈されます。

if (!girl.HasShortHair)
{
    if (girl.IsBokuGirl)
    {
        Console.Write("かわいいね");
    }
    else
    {
        Console.Write("かわいいね");
    }
}

するとどうでしょう、「女の子がショートヘアでない場合、ボクっ娘であればコンソール出力、ボクっ娘でなくてもコンソール出力」「女の子がショートヘアの場合は何もしない」というコードになってしまいました。意図が真逆になっています。

なので、こういうケースでは{}を使ってelseがどのifに対応しているものなのかを明示的に記載する必要があります。

if (!girl.HasShortHair)
{
    if (girl.IsBokuGirl)
        Console.Write("かわいいね");
}
else
    Console.Write("かわいいね");

上記のようにすれば問題なく、本来の要件を満たす条件判定となります。個人的な好みとしてはif{}を付けるならelseにも{}を(単一処理でも)付けたいです。

if{}を省略する場合は、シンプルな処理であればタイプ量も減りシンプルで見通しの良いコードになりますが、複数条件が入り組んだ式の場合は注意が必要です。

※説明のために意図的に分かりにくく書きましたが、上記の例であれば

if (girl.HasShortHair || girl.IsBokuGirl)
    Console.Write("かわいいね");

のようにロジックを見直して吸収できたりもするので、柔軟に考えてみると良いと思います。


  1. C#の歴史的背景に詳しくないのですが、「もともとifはそれに続く単一の処理をするのであり、{}で複数の処理を単一の処理っぽくしているのであって、省略とかではなく本来{}がないのが成り立ち的には正しいのである」とか…。