C#_単項・二項・三項演算子


どのプログラミング言語でもあるように、C#でも値同士の計算や評価の為の **"演算子"** が存在します。
演算子を有効に活用することでソースコードが簡潔に分かりやすくなるので、積極的に使っていきましょう

本文は以下の記事の内容を前提に記述しています。

* [C#_変数宣言と型・キャスト](https://qiita.com/MtBigYashi/items/a35b6ad1514be867f14a)

## 演算子

演算子にはいくつかの種類があります。

* 変数1つだけで作用する「**単項演算子**」

* 変数2つの間で作用する「**二項演算子**」

* 変数3つで作用する「**三項演算子**」

普段使用するのはほとんどが二項演算子なので、まずそれから書いていきます。

## 二項演算子

たくさんありますが、基本的に値型に対して適用できます。

* <u>値型に対する二項演算子</u>

    |演算子|内容|使用例|
    |:---:|:---:|:---:|
    |x + y|xとyの和|8 + 5 = 13|
    |x - y|xとyの差|8 - 5 = 3|
    |x * y|xとyの積|8 * 5 = 40|
    |x / y|xとyの商|8 / 5 = 1.6 (整数型なら1)|
    |x % y|xとyの剰余|8 % 5 = 3|
    |x & y|xとyの論理積|12 & 5 = (1100) & (0101) = (0100) = 4|
    |x &#124; y|xとyの論理和|12 &#124; 5 = (1100) &#124; (0101) = (1101) = 13|
    |x ^ y|xとyの排他的論理和|12 ^ 5 = (1100) ^ (0101) = (1001) = 9|
    |x << y|xをy分左シフト|12 << 2 = (1100) << 2 = (110000) = 48|
    |x >> y|xをy分右シフト|12 >> 2 = (1100) >> 2 = (11) = 3|
    |x = y|xへyを代入|x = 5 (xに5が入る)|
    |x == y|xとyが等しいかどうか|x = 5 ⇒ x == 5 → true / x == 8 → false|
    |x != y|xとyが異なるかどうか|x = 5 ⇒ x != 5 → false / x != 8 → true|
    |x < y|xがyより小さいかどうか|x = 5 ⇒ x < 5 → false / x < 8 → true|
    |x <= y|xがy以下かどうか|x = 5 ⇒ x <= 5 → true / x <= 8 → true|
    |x > y|xがyより大きいかどうか|x = 5 ⇒ x > 5 → false / x > 8 → false|
    |x >= y|xがy以上かどうか|x = 5 ⇒ x >= 5 → true / x >= 8 → false|
    |x && y|xかつy(AND演算)|x, yが共にtrue ⇒ x && y → true / そうでなければfalse|
    |x &#124;&#124; y|xまたはy(OR演算)|x, yの少なくとも一方がtrue ⇒ x &#124;&#124; y → true / そうでなければfalse|

* <u>文字列型に対する二項演算子</u>

    |演算子|内容|使用例|
    |:---:|:---:|:---:|
    |x + y|xとyの文字列結合|"abc" + "def" = "abcdef"|

その他、参照型に対しては代入演算子以外は基本的に定義されていません。
ただし、自分で定義することもできます。

次に二項演算子の中でも少し特殊な **"複合代入演算子"** を列挙していきます
上記二項演算子と代入演算子を組み合わせた内容になっています。

* <u>複合代入演算子</u>

    |演算子|内容|
    |:---:|:---:|
    |x += y|x = x + y|
    |x -= y|x = x - y|
    |x *= y|x = x * y|
    |x /= y|x = x / y|
    |x %= y|x = x % y|
    |x &= y|x = x & y|
    |x &#124;= y|x = x &#124; y|
    |x ^= y|x = x ^ y|
    |x <<= y|x = x << y|
    |x >>= y|x = x >> y|

## 単項演算子

次に変数1つに対して作用する演算子を紹介していきます。

* <u>単項演算子</u>

    |演算子|内容|使用例|
    |:---:|:---:|:---:|
    |+x|xそのまま|x = 5 ⇒ +x = 5|
    |-x|xの符号反転|x = 5 ⇒ -x = -5|
    |x++|x=x+1(後置インクリメント)|x = 5 ⇒ x++ = 6|
    |++x|x=x+1(前置インクリメント)|x = 5 ⇒ ++x = 6|
    |x--|x=x-1(後置デクリメント)|x = 5 ⇒ x-- = 4|
    |--x|x=x-1(前置デクリメント)|x = 5 ⇒ x-- = 4|
    |!x|xの否定|x = true ⇒ !x = false|
    |~x|xの補数(ビット反転)|int x = 5 ⇒ ~x = -6|

さて、インクリメント・デクリメントには前置/後置の2種類がありますが、どちらもそれ単体としては結果が変わらないように見えます。
ではどういう使い分けがあるかというと「結果を返すタイミング」が違います。

* a++は、aを返してからaに+1します

* ++aは、aに+1してからaを返します

例).

```C#:Program.cs
int a = 5;
Console.WriteLine(a++); // aを表示してからa = a + 1
Console.WriteLine(++a); // a = a + 1してからaを表示
```

```TXT:出力
> 5
> 7
```

デクリメントについても全く同じ動作になります。

## 三項演算子

次に、C#における唯一の三項演算子を紹介します。

* <u>三項演算子</u>

    |演算子|内容|使用例|
    |:---:|:---:|:---:|
    |x ? y : z|x = true ⇒ yを返す / x = false ⇒ zを返す|x = 5 ⇒ x == 5 ? "a" : "b" → "a" / x == 8 ? "a" : "b" → "b"|

三項演算子は適度に使用することで有効に活用することができますが、
使い方や頻度によっては著しくソースコードの可読性を落とすこともある諸刃の剣です。

使う場面は慎重に選んで使っていきましょう

## null合体演算子

最後に、nullという特殊な概念を扱う為の演算子を紹介します。

**"null"** とは、他の言語ではnullptrやNothing, nilなどとも表現される、「何ものでもない」「何も指していない」ことを表現します。
プログラムにおいてnullに対してアクセスするとエラーになる為、慎重に扱う必要がありますが、それを簡潔にする演算子がnull合体演算子になります。

三項演算子でnullかどうかのチェックを使用したパターンを1つにまとめたものです。

* <u>null合体演算子</u>

    |演算子|内容|
    |:---:|:---:|
    |x ?? y|xがnullでなければxを、xがnullならばyを返す|
    |x ??= y|xがnullならば、xにyを代入する（xがnullじゃなければxのまま）|

なお、このnull合体演算子は古い開発環境では認識できない場合もあるので注意しましょう（.NET Coreであれば大丈夫のはず）

C#で使用される代表的な演算子は以上になります。
最後に参考URLを貼っておきます。

* [C# 演算子と式 (Microsoft Docs)](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/)

* [組込み演算子 (未確認飛行C)](https://ufcpp.net/study/csharp/st_operator.html)