.net column

.NET開発者のためのブログメディア

C#の||の使い方をわかりやすく解説!||の落とし穴と応用・|との違い

2020年11月12日
SE
C#の||で記述して実行結果が思った通りにならないことがあったのですが。
PM
短絡評価と呼ばれる動作がおこったのでしょう。||を使う時はこれに注意する必要があります。

C#の||とは?


C#の||は演算子の一つで、正式な名前は「条件付き論理OR演算子」と言います。「A || B」のように記述して「AまたはB」という意味で使われます。最も多く使われるのは以下のようなif文です。

 

int a = 0;
int b = 1;

 

if (a==1 || b==1)
{
Console.WriteLine(“”aまたはbのうちどちらかが1です。””);
}

 

これを実行すると、bが1なので以下のように表示されます。

 

aまたはbのうちどちらかが1です。

||の落とし穴

||については注意すべき点があります。以下のC#サンプルをご覧ください。

 

public static string Disp(string str)
{
Console.WriteLine(str);
return str;
}

 

public static void Main()
{
if (Disp(“”abc””) == “”123″” || Disp(“”123″”) == “”123″”)
{
Console.WriteLine(“”どちらかが123でした。””);
}
if (Disp(“”abc””) == “”abc”” || Disp(“”def””) == “”abc””)
{
Console.WriteLine(“”どちらかがabcでした。””);
}
}

||のサンプルの実行結果は…

このC#サンプルは、Dispという渡された文字列を表示して返すだけのメソッドを、if文で||でつないで呼び出しています。そしてif文の結果を表示します。実行すると以下のように表示されます。

 

abc
123
どちらかが123でした。
abc
どちらかがabcでした。

 

1つ目のif文ではDisp(“”abc””)とDisp(“”123″”)が呼ばれて、後者の戻り値が””123″”なので「どちらかが123でした。」と表示されます。
2つ目のif文ではDisp(“”abc””)が呼ばれて、戻り値が””abc””なので「どちらかがabcでした。」と表示されます。

短絡評価の動作に注意しつつ活用もする

2つ目のif文のDisp(“”def””)は実行されませんでした。1つ目の結果が成立すると、もうひとつの方は実行されないのです。||を使う時はこれに注意する必要があります。なおこの||の動作は「短絡評価」と呼ばれます。

 

逆にこの動作を活用して、以下のようにすると効率の良いC#プログラムを作ることができます。1つ目の条件が成立すれば、処理の重いメソッドを実行せずに済みます。

 

(処理の軽いメソッド) || (処理の重いメソッド)

||の応用

||は以下のように3つ以上、いくつでも連ねることもできます。その場合は左から順に判定され、成立した時点で残りは実行されません。

 

if (Disp(“”abc””) == “”123″” || Disp(“”123″”) == “”123″” || Disp(“”456″”) == “”123″”)
{
Console.WriteLine(“”どちらかが123でした。””);
}

 

なお||はif文でしか使えないわけではありません。以下のように結果のTrue/Falseを代入することもできます。

 

bool ret = Disp(“”abc””) == “”123″” || Disp(“”123″”) == “”123″”;

||とは別に|もある

実は演算子には||と似た|もあります。名前はOR論理演算子と言います。|も||と同じように以下のように「または」という意味で使うことができます。

 

int a = 0;
int b = 1;

 

if (a == 1 | b == 1) // ||でなく|を使う
{
Console.WriteLine(“”aまたはbのうちどちらかが1です。””);
}

||と|の違い

||と|はどう違うのでしょうか?それはDispメソッドを使用したC#サンプルで、以下のように||を|にすればわかります。

 

if (Disp(“”abc””) == “”abc”” | Disp(“”def””) == “”abc””)
{
Console.WriteLine(“”どちらかがabcでした。””);
}

 

このif文の結果は以下になります。

 

abc
def
どちらかがabcでした。

 

||の時と違い、2つ目のDisp(“”def””)の方も実行されていますね。これが||との違いです。||は条件が成立した時点で残りは実行しませんが、|は全て実行するのです。

||と並んでよく使用される&&

C#で||と共によく使う演算子に&&があります。名前は条件付き論理AND演算子と言います。以下のように、全ての条件が成立するかどうかをチェックできます。

 

int a = 1;
int b = 1;
int c = 1;

 

if (a == 1 && b == 1 && c == 1)
{
Console.WriteLine(“”全てが1です。””);
}

&&も短絡評価としての動作をする

&&もまた短絡評価としての動作をします。以下のC#サンプルをご覧ください。

 

public static string Disp(string str)
{
Console.WriteLine(str);
return str;
}
public static void Main()
{
if (Disp(“”abc””) == “”123″” && Disp(“”def””) == “”123″”)
{
Console.WriteLine(“”どちらも123でした。””);
}
}

&&と&の関係は||と|と同じ

上のC#サンプルの実行結果は、

 

abc

 

となります。一つ目のDisp(“”abc””)が成立しないので、全てが成立しないことが確定するためそこで処理を打ち切って、Disp(“”def””)は実行しません。||と同様に不要な処理は行わないのです。そして上のサンプルのif文を以下のように&&を&にすると、

 

if (Disp(“”abc””) == “”123″” & Disp(“”def””) == “”123″”)

 

実行結果は

 

abc
def

 

となります。||と|の関係のように、&も&&と違って全ての処理を実行するということですね。

||と&&の優先度

||と&&の優先度はどうなっているのでしょうか。以下のC#サンプルをご覧ください。

 

public static string Disp(string str)
{
Console.WriteLine(str);
return str;
}
public static void Main()
{
if (Disp(“”abc””) == “”123″” || Disp(“”def””) == “”123″”
&&
Disp(“”ghi””) == “”123″” || Disp(“”jkl””) == “”123″”)
{
Console.WriteLine(“”条件成立です。””);
}
}

||よりも&&の方が優先度が高い

上のC#サンプルは「Disp(“”abc””)かDisp(“”def””)が””123″”で、かつ、Disp(“”ghi””)かDisp(“”jkl””)が””123″”」としているつもりです。ところが結果は、

 

abc
def
jkl

 

となります。Disp(“”abc””)もDisp(“”def””)も””123″”ではないのでそこで処理が終わるべきなのにDisp(“”jkl””)が実行されてしまっています。その理由は、||よりも&&の方が優先度が高いからです。

括弧を使えば優先順位を変えられる

上のサンプルのままだと、「Disp(“”abc””)が””123″”か、 Disp(“”def””)とDisp(“”ghi””)の両方が””123″”か、 Disp(“”jkl””)が””123″”」という条件判断になってしまっているのです。最初の意図通りにするには、以下のように括弧を使います。

 

if ((Disp(“”abc””) == “”123″” || Disp(“”def””) == “”123″”)
&&
(Disp(“”ghi””) == “”123″” || Disp(“”jkl””) == “”123″”))
{
Console.WriteLine(“”条件成立です。””);
}

 

これで実行結果は以下になります。最初の括弧内が成立しないので、&&によりそこで処理が打ち切られていますね。

 

abc
def

SE
||の記述をもう一度確認してみます。
PM
||と&&の動作について正しく理解して、間違いがないようにしましょう。

||と&&を正しく使いこなそう

C#の||と&&について解説しましたが、ご理解頂けましたでしょうか。論理演算子の動作を正しく理解しないと致命的な間違いを引き起こすので、しっかり把握しておきましょう。


.NET分野でのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

求人一覧

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)