C#演算子の種類と使い方を初心者向けに一覧でわかりやすく解説
はじめに
C#を学び始めると、必ず出てくるのが「演算子」です。演算子とは、+、-、==、&&、?? のように、計算・比較・代入・条件判定などを行うための記号やキーワードのことです。
たとえば、次のコードでは + が演算子です。
C#int result = 10 + 5;
Console.WriteLine(result);
このコードでは、10 と 5 を足し算して、結果を result に代入しています。C#の演算子は、計算だけでなく、条件分岐、繰り返し処理、nullチェック、型判定、非同期処理など、さまざまな場面で使われます。
この記事では、C#演算子の種類と使い方を初心者向けに一覧でわかりやすく解説します。基本的な算術演算子から、実務でよく使うnull関連演算子、ラムダ演算子、await演算子まで、サンプルコード付きで理解できるように紹介します。
1. C#の演算子とは?初心者向けに基本をわかりやすく解説
C#の演算子を理解すると、コードの意味を読み取りやすくなり、自分で条件分岐や計算処理を書けるようになります。まずは、演算子の基本から確認していきましょう。
1-1. 演算子とは「計算・比較・代入などを行う記号」のこと
演算子とは、値に対して何らかの処理を行う記号やキーワードです。
たとえば、次のようなものがあります。
C#int a = 10 + 5;
bool result = a > 10;
このコードでは、=、+、> が演算子です。
= は右側の値を左側の変数に代入します。+ は足し算を行います。> は左側の値が右側の値より大きいかどうかを判定します。
C#では、算術演算子、代入演算子、比較演算子、論理演算子、ビット演算子、条件演算子、null関連演算子など、多くの演算子が用意されています。Microsoft公式のC#言語リファレンスでも、演算子と式はC#の重要な構文として整理されています。
1-2. C#における演算子とオペランドの関係
演算子によって処理される値のことを「オペランド」と呼びます。
C#int answer = 10 + 3;
この場合、+ が演算子、10 と 3 がオペランドです。
演算子には、オペランドの数によって種類があります。
C#int x = 10;
int y = -x; // 単項演算子
int z = x + 5; // 二項演算子
string result = x > 5 ? "大きい" : "小さい"; // 三項演算子
単項演算子は、1つの値に対して使います。二項演算子は、2つの値の間で使います。三項演算子は、条件に応じて2つの値のどちらかを返します。
1-3. 演算子を理解するとできるようになること
C#演算子を理解すると、次のような処理を書けるようになります。
C#int price = 1000;
int tax = 100;
int total = price + tax;
if (total >= 1000)
{
Console.WriteLine("1000円以上です");
}
この例では、+ で合計金額を計算し、>= で1000円以上かどうかを判定しています。
さらに、論理演算子を使えば複数条件を組み合わせられます。
C#int age = 25;
bool hasTicket = true;
if (age >= 18 && hasTicket)
{
Console.WriteLine("入場できます");
}
&& は「かつ」を表す演算子です。このように、演算子を使いこなすことで、計算、判定、条件分岐、繰り返し処理など、プログラムの基本的な処理を組み立てられるようになります。
1-4. 初心者がつまずきやすい演算子のポイント
C#初心者がつまずきやすいポイントは、主に次のようなものです。
C#int x = 10;
if (x == 10)
{
Console.WriteLine("10です");
}
= は代入、== は比較です。この違いを混同すると、意図しないコードになります。
また、整数同士の割り算にも注意が必要です。
C#int result = 5 / 2;
Console.WriteLine(result); // 2
5 / 2 は 2.5 ではなく 2 になります。これは、整数同士の割り算では小数部分が切り捨てられるためです。
さらに、&& と &、|| と | の違い、++x と x++ の違い、演算子の優先順位なども、初心者が混乱しやすいポイントです。
2. C#演算子の種類一覧
C#には多くの演算子があります。最初からすべてを暗記する必要はありませんが、どのような種類があるかを一覧で把握しておくと、コードを読むときに役立ちます。
2-1. 算術演算子
算術演算子は、数値の計算に使う演算子です。
| 演算子 | 意味 | 例 |
|---|---|---|
+ | 加算 | a + b |
- | 減算 | a - b |
* | 乗算 | a * b |
/ | 除算 | a / b |
% | 剰余 | a % b |
++ | 1増やす | a++ |
-- | 1減らす | a-- |
C#の算術演算子には、加算、減算、乗算、除算、剰余、インクリメント、デクリメントなどがあります。数値型の計算でよく使われる基本的な演算子です。
2-2. 代入演算子
代入演算子は、変数に値を入れるために使います。
| 演算子 | 意味 | 例 |
|---|---|---|
= | 代入 | x = 10 |
+= | 加算して代入 | x += 5 |
-= | 減算して代入 | x -= 5 |
*= | 乗算して代入 | x *= 5 |
/= | 除算して代入 | x /= 5 |
%= | 剰余を代入 | x %= 5 |
??= | nullの場合だけ代入 | name ??= "未設定" |
複合代入演算子は、x = x + 5 のような処理を x += 5 と短く書ける演算子です。C#では算術演算子、論理演算子、ビット演算子、シフト演算子などで複合代入を使えます。
2-3. 比較演算子
比較演算子は、2つの値を比較して true または false を返します。
| 演算子 | 意味 | 例 |
|---|---|---|
== | 等しい | a == b |
!= | 等しくない | a != b |
> | より大きい | a > b |
< | より小さい | a < b |
>= | 以上 | a >= b |
<= | 以下 | a <= b |
比較演算子は、if文やwhile文などの条件式で非常によく使います。
2-4. 論理演算子
論理演算子は、複数の条件を組み合わせるために使います。
| 演算子 | 意味 | 例 |
|---|---|---|
&& | AND、かつ | a && b |
| ` | ` | |
! | NOT、否定 | !a |
& | 論理ANDまたはビットAND | a & b |
| ` | ` | 論理ORまたはビットOR |
^ | XOR | a ^ b |
&& と || は条件分岐でよく使われます。&、|、^ はbool値に対しても使えますが、整数に対して使うとビット演算になります。
2-5. インクリメント・デクリメント演算子
インクリメント演算子とデクリメント演算子は、値を1だけ増減させます。
C#int count = 0;
count++;
Console.WriteLine(count); // 1
count--;
Console.WriteLine(count); // 0
++ は1増やし、-- は1減らします。for文のカウンタ変数でよく使われます。
2-6. ビット演算子
ビット演算子は、整数を2進数のビット単位で操作する演算子です。
| 演算子 | 意味 |
|---|---|
& | ビットAND |
| ` | ` |
^ | ビットXOR |
~ | ビット補数 |
<< | 左シフト |
>> | 右シフト |
>>> | 符号なし右シフト |
C#のビット演算子とシフト演算子は、整数型や char 型のオペランドに対して使われます。
2-7. 条件演算子
条件演算子は、条件によって返す値を切り替える演算子です。
C#int score = 80;
string result = score >= 60 ? "合格" : "不合格";
条件 ? trueの場合 : falseの場合 という形で書きます。三項演算子とも呼ばれます。
2-8. null関連演算子
null関連演算子は、nullチェックを簡潔に書くために使います。
| 演算子 | 意味 |
|---|---|
?? | 左辺がnullでなければ左辺、nullなら右辺 |
??= | 左辺がnullの場合だけ代入 |
?. | nullでなければメンバーにアクセス |
?[] | nullでなければ要素にアクセス |
! | null免除演算子 |
?? と ?. は、NullReferenceException を防ぐために実務でもよく使われます。
2-9. 型チェック・型変換演算子
型チェックや型変換では、次のような演算子を使います。
| 演算子 | 意味 |
|---|---|
is | 型やパターンに一致するか判定 |
as | 安全に型変換 |
(型) | キャスト |
typeof | 型情報を取得 |
is、as、キャスト、typeof は、オブジェクトの型を確認したり、別の型として扱ったりするときに使います。
2-10. その他のよく使う演算子
C#では、次のような演算子もよく使われます。
| 演算子 | 意味 |
|---|---|
. | メンバーアクセス |
[] | インデックスアクセス |
=> | ラムダ式、式形式メンバー |
nameof | 名前を文字列として取得 |
new | インスタンス生成 |
await | 非同期処理の結果を待つ |
switch 式 | 条件に応じた値を返す |
特に .、[]、new はC#の基本文法で頻繁に使います。
3. 算術演算子の使い方
算術演算子は、C#演算子の中でも最初に覚えるべき基本です。数値計算を行うときに使います。
3-1. 足し算・引き算・掛け算・割り算の基本
C#では、足し算、引き算、掛け算、割り算を次のように書きます。
C#int a = 10;
int b = 3;
Console.WriteLine(a + b); // 13
Console.WriteLine(a - b); // 7
Console.WriteLine(a * b); // 30
Console.WriteLine(a / b); // 3
+ は加算、- は減算、* は乗算、/ は除算です。
プログラミングでは、掛け算に × ではなく *、割り算に ÷ ではなく / を使う点に注意しましょう。
3-2. 剰余演算子「%」の使い方
% は、割り算の余りを求める演算子です。
C#int result = 10 % 3;
Console.WriteLine(result); // 1
10 を 3 で割ると、商は 3、余りは 1 です。そのため、10 % 3 の結果は 1 になります。
剰余演算子は、偶数・奇数の判定でよく使われます。
C#int number = 8;
if (number % 2 == 0)
{
Console.WriteLine("偶数です");
}
else
{
Console.WriteLine("奇数です");
}
number % 2 が 0 なら偶数、1 なら奇数と判断できます。
3-3. 整数同士の割り算で小数点が切り捨てられる理由
C#では、整数同士を割り算すると、結果も整数になります。
C#int result = 5 / 2;
Console.WriteLine(result); // 2
5 / 2 は数学的には 2.5 ですが、int 同士の計算なので小数部分が切り捨てられ、結果は 2 になります。
小数まで求めたい場合は、double や decimal を使います。
C#double result = 5.0 / 2.0;
Console.WriteLine(result); // 2.5
また、片方だけを小数にしても、小数の計算になります。
C#double result = 5 / 2.0;
Console.WriteLine(result); // 2.5
3-4. 算術演算子のサンプルコード
次のコードは、商品の価格、個数、消費税を計算する例です。
C#int price = 1200;
int count = 3;
double taxRate = 0.1;
int subtotal = price * count;
double tax = subtotal * taxRate;
double total = subtotal + tax;
Console.WriteLine($"小計: {subtotal}円");
Console.WriteLine($"税額: {tax}円");
Console.WriteLine($"合計: {total}円");
実行結果は次のようになります。
小計: 3600円
税額: 360円
合計: 3960円
算術演算子は、金額計算、平均値の計算、カウント処理、割合計算など、多くの場面で使います。
4. 代入演算子の使い方
代入演算子は、変数に値を入れるための演算子です。C#では、単純な代入だけでなく、計算と代入を同時に行う複合代入演算子もよく使います。
4-1. 基本の代入演算子「=」
= は、右側の値を左側の変数に代入します。
C#int number;
number = 10;
Console.WriteLine(number); // 10
変数宣言と同時に代入することもできます。
C#string name = "田中";
int age = 25;
ここで注意したいのは、= は「等しい」という意味ではなく、「代入する」という意味だということです。
4-2. 複合代入演算子「+=」「-=」「*=」「/=」「%=」
複合代入演算子を使うと、変数の現在の値に対して計算し、その結果を再び同じ変数に代入できます。
C#int x = 10;
x += 5; // x = x + 5 と同じ
Console.WriteLine(x); // 15
x -= 3; // x = x - 3 と同じ
Console.WriteLine(x); // 12
x *= 2; // x = x * 2 と同じ
Console.WriteLine(x); // 24
x /= 4; // x = x / 4 と同じ
Console.WriteLine(x); // 6
x %= 4; // x = x % 4 と同じ
Console.WriteLine(x); // 2
複合代入を使うと、コードを短く書けます。
4-3. 代入演算子を使うとコードが短くなる例
たとえば、ゲームのスコアを加算する処理を考えてみましょう。
C#int score = 100;
score = score + 50;
Console.WriteLine(score); // 150
このコードは、+= を使って次のように書けます。
C#int score = 100;
score += 50;
Console.WriteLine(score); // 150
どちらも結果は同じですが、+= の方が簡潔です。
4-4. 代入演算子で初心者が間違えやすいポイント
初心者がよく間違えるのは、= と == の違いです。
C#int x = 10;
if (x == 10)
{
Console.WriteLine("xは10です");
}
条件式では、等しいかどうかを調べるために == を使います。
= は代入です。
C#x = 20;
== は比較です。
C#x == 20
C#では、if文の条件には bool 型が必要なので、if (x = 10) のようなコードは通常エラーになります。ただし、bool型の変数では代入が条件式として成立するケースもあるため、意味をしっかり理解しておくことが大切です。
5. 比較演算子の使い方
比較演算子は、2つの値を比較して true または false を返します。if文やwhile文など、条件分岐で非常によく使われます。
5-1. 等しいかを調べる「==」
== は、左辺と右辺が等しいかどうかを調べる演算子です。
C#int a = 10;
int b = 10;
Console.WriteLine(a == b); // True
文字列の比較にも使えます。
C#string name = "C#";
Console.WriteLine(name == "C#"); // True
5-2. 等しくないかを調べる「!=」
!= は、左辺と右辺が等しくないかどうかを調べる演算子です。
C#int a = 10;
int b = 5;
Console.WriteLine(a != b); // True
ログイン状態や入力値の確認などでよく使います。
C#string input = "admin";
if (input != "")
{
Console.WriteLine("入力されています");
}
5-3. 大小比較を行う「>」「<」「>=」「<=」
数値の大小比較には、次の演算子を使います。
C#int score = 75;
Console.WriteLine(score > 80); // False
Console.WriteLine(score < 80); // True
Console.WriteLine(score >= 60); // True
Console.WriteLine(score <= 100); // True
> はより大きい、< はより小さい、>= は以上、<= は以下を表します。
5-4. if文で比較演算子を使う例
比較演算子は、if文と組み合わせて使うことが多いです。
C#int score = 85;
if (score >= 80)
{
Console.WriteLine("優秀です");
}
else if (score >= 60)
{
Console.WriteLine("合格です");
}
else
{
Console.WriteLine("不合格です");
}
このコードでは、点数によって表示するメッセージを変えています。
5-5. 「=」と「==」の違い
= と == は見た目が似ていますが、意味はまったく違います。
C#int x = 10; // 代入
bool result = x == 10; // 比較
= は値を入れる演算子です。== は等しいかどうかを調べる演算子です。
初心者のうちは、条件式の中では == を使う、と意識しておくと混乱しにくくなります。
6. 論理演算子の使い方
論理演算子は、複数の条件を組み合わせたり、条件を反転させたりするときに使います。
6-1. AND条件を表す「&&」
&& は、左辺と右辺の両方が true の場合に true を返します。
C#int age = 20;
bool hasTicket = true;
if (age >= 18 && hasTicket)
{
Console.WriteLine("入場できます");
}
この例では、年齢が18歳以上で、かつチケットを持っている場合だけ入場できます。
6-2. OR条件を表す「||」
|| は、左辺または右辺のどちらかが true の場合に true を返します。
C#bool isMember = false;
bool hasCoupon = true;
if (isMember || hasCoupon)
{
Console.WriteLine("割引対象です");
}
この例では、会員であるか、クーポンを持っている場合に割引対象になります。
6-3. NOT条件を表す「!」
! は、条件を反転させる演算子です。
C#bool isLoggedIn = false;
if (!isLoggedIn)
{
Console.WriteLine("ログインしてください");
}
isLoggedIn が false のとき、!isLoggedIn は true になります。
6-4. 複数条件を組み合わせる方法
論理演算子を使うと、複数の条件を組み合わせられます。
C#int age = 25;
bool hasLicense = true;
bool isSuspended = false;
if (age >= 18 && hasLicense && !isSuspended)
{
Console.WriteLine("運転できます");
}
この例では、18歳以上、免許を持っている、免許停止中ではない、という3つの条件を満たした場合に処理を実行します。
条件が複雑になる場合は、変数に分けると読みやすくなります。
C#bool isAdult = age >= 18;
bool canDrive = isAdult && hasLicense && !isSuspended;
if (canDrive)
{
Console.WriteLine("運転できます");
}
6-5. 論理演算子の短絡評価とは
&& と || には、短絡評価という仕組みがあります。
&& の場合、左辺が false なら、右辺を評価しなくても結果は false です。そのため、右辺は実行されません。
C#string? name = null;
if (name != null && name.Length > 0)
{
Console.WriteLine(name);
}
このコードでは、name != null が false の場合、name.Length > 0 は評価されません。そのため、null参照によるエラーを防げます。
|| の場合は、左辺が true なら、右辺を評価しなくても結果は true です。C#では、条件付き論理AND &&、条件付き論理OR ||、null合体演算子、null条件演算子、条件演算子など、一部の演算子が条件によってオペランドの評価を省略します。
7. インクリメント・デクリメント演算子の使い方
インクリメント演算子とデクリメント演算子は、数値を1だけ増やしたり減らしたりする演算子です。
7-1. 「++」で値を1増やす方法
++ は、変数の値を1増やします。
C#int count = 0;
count++;
Console.WriteLine(count); // 1
これは次のコードと同じ意味です。
C#count = count + 1;
また、次のようにも書けます。
C#count += 1;
7-2. 「--」で値を1減らす方法
-- は、変数の値を1減らします。
C#int count = 5;
count--;
Console.WriteLine(count); // 4
これは次のコードと同じ意味です。
C#count = count - 1;
7-3. 前置と後置の違い
++ と -- には、前置と後置があります。
C#int x = 5;
Console.WriteLine(++x); // 6
Console.WriteLine(x); // 6
前置インクリメント ++x は、値を増やしてから使います。
一方、後置インクリメント x++ は、値を使ってから増やします。
C#int y = 5;
Console.WriteLine(y++); // 5
Console.WriteLine(y); // 6
7-4. for文でよく使われる例
インクリメント演算子は、for文でよく使われます。
C#for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
このコードでは、ループが1回実行されるたびに i++ によって i が1増えます。
実行結果は次の通りです。
0
1
2
3
4
7-5. 前置・後置で結果が変わる注意点
前置と後置は、単独で使う場合は結果が同じに見えます。
C#int a = 1;
a++;
int b = 1;
++b;
この場合、どちらも最終的な値は 2 です。
しかし、代入やメソッド呼び出しと組み合わせると結果が変わります。
C#int x = 1;
int y = x++;
Console.WriteLine(x); // 2
Console.WriteLine(y); // 1
x++ は「現在のxを使ったあとで増やす」ため、y には 1 が入ります。
C#int x = 1;
int y = ++x;
Console.WriteLine(x); // 2
Console.WriteLine(y); // 2
++x は「xを増やしてから使う」ため、y には 2 が入ります。
初心者のうちは、前置・後置を複雑な式の中で使わず、単独の行で使うと安全です。
8. ビット演算子の使い方
ビット演算子は、整数を2進数のビット単位で操作する演算子です。初心者向けのアプリ開発では頻度は高くありませんが、フラグ管理、低レベル処理、パフォーマンス重視の処理などで使われます。
8-1. ビット演算子とは
コンピューター内部では、数値は2進数で扱われます。たとえば、5 は2進数で 0101、3 は 0011 のように表せます。
ビット演算子は、このような2進数の各桁に対して処理を行います。
C#int a = 5; // 0101
int b = 3; // 0011
ビット演算は慣れるまで難しく感じますが、考え方は「各ビットを1つずつ比べる」というものです。
8-2. AND演算「&」
& は、両方のビットが 1 の場合だけ 1 になります。
C#int a = 5; // 0101
int b = 3; // 0011
int result = a & b;
Console.WriteLine(result); // 1
0101 と 0011 をビットANDすると 0001 になり、10進数では 1 です。
8-3. OR演算「|」
| は、どちらか一方のビットが 1 なら 1 になります。
C#int a = 5; // 0101
int b = 3; // 0011
int result = a | b;
Console.WriteLine(result); // 7
0101 と 0011 をビットORすると 0111 になり、10進数では 7 です。
8-4. XOR演算「^」
^ は、左右のビットが異なる場合に 1 になります。
C#int a = 5; // 0101
int b = 3; // 0011
int result = a ^ b;
Console.WriteLine(result); // 6
0101 と 0011 をXORすると 0110 になり、10進数では 6 です。
8-5. 補数演算「~」
~ は、ビットを反転する演算子です。0 は 1 に、1 は 0 になります。
C#int a = 5;
int result = ~a;
Console.WriteLine(result); // -6
結果が -6 になるのは、C#の整数が符号付き整数として表現されるためです。ビット補数は初心者には少し難しいため、最初は「ビットを反転する演算子」と理解しておけば十分です。
8-6. シフト演算「<<」「>>」
<< は左シフト、>> は右シフトです。ビットを左右に移動します。
C#int a = 4; // 0100
Console.WriteLine(a << 1); // 8
Console.WriteLine(a >> 1); // 2
左シフトは、数値を2倍、4倍、8倍のように増やす処理に近い動きをします。右シフトは、2で割る処理に近い動きをします。
8-7. ビット演算子を使う場面
ビット演算子は、次のような場面で使われます。
C#[Flags]
enum Permission
{
None = 0,
Read = 1,
Write = 2,
Execute = 4
}
Permission permission = Permission.Read | Permission.Write;
bool canRead = (permission & Permission.Read) == Permission.Read;
Console.WriteLine(canRead); // True
この例では、Read と Write の権限をビットORで組み合わせ、ビットANDで Read 権限が含まれているかを確認しています。
通常のWebアプリや業務アプリでは、ビット演算子を頻繁に使う場面は多くありません。必要になったときに学べば十分です。
9. 条件演算子の使い方
条件演算子は、条件によって返す値を切り替える演算子です。if文を短く書きたいときに便利です。
9-1. 三項演算子「条件 ? 真の場合 : 偽の場合」とは
条件演算子は、次の形で書きます。
C#条件 ? trueの場合の値 : falseの場合の値
たとえば、点数が60点以上なら「合格」、そうでなければ「不合格」とする場合は次のように書けます。
C#int score = 75;
string result = score >= 60 ? "合格" : "不合格";
Console.WriteLine(result); // 合格
条件演算子 ?: は、条件式の結果が true か false かによって、2つの式のどちらかを返します。
9-2. if文を三項演算子で書き換える例
次のif文を見てください。
C#int score = 75;
string result;
if (score >= 60)
{
result = "合格";
}
else
{
result = "不合格";
}
このコードは、三項演算子を使うと次のように書けます。
C#int score = 75;
string result = score >= 60 ? "合格" : "不合格";
結果は同じですが、三項演算子を使うとコードが短くなります。
9-3. 三項演算子を使うメリット
三項演算子のメリットは、短い条件分岐を1行で書けることです。
C#int age = 20;
string message = age >= 18 ? "成人です" : "未成年です";
値を代入するだけのシンプルな条件分岐では、if文よりも読みやすくなる場合があります。
また、メソッドの戻り値にも使えます。
C#static string GetResult(int score)
{
return score >= 60 ? "合格" : "不合格";
}
9-4. 三項演算子を使いすぎると読みにくくなる注意点
三項演算子は便利ですが、使いすぎると読みにくくなります。
C#string result = score >= 80 ? "優秀" : score >= 60 ? "合格" : "不合格";
このように条件が入れ子になると、初心者には読みづらくなります。
複雑な条件分岐では、if文を使った方がわかりやすいです。
C#if (score >= 80)
{
result = "優秀";
}
else if (score >= 60)
{
result = "合格";
}
else
{
result = "不合格";
}
コードは短ければよいわけではありません。読みやすさを優先して使い分けましょう。
10. null関連演算子の使い方
C#では、値が存在しないことを表す null を扱う場面が多くあります。null関連演算子を使うと、nullチェックを簡潔に書けます。
10-1. null合体演算子「??」
?? は、左辺がnullでなければ左辺を返し、nullなら右辺を返す演算子です。
C#string? name = null;
string displayName = name ?? "未設定";
Console.WriteLine(displayName); // 未設定
name がnullなので、右辺の "未設定" が使われます。
C#string? name = "佐藤";
string displayName = name ?? "未設定";
Console.WriteLine(displayName); // 佐藤
name がnullでなければ、左辺の値がそのまま使われます。C#の ?? は、左辺がnullでない場合は左辺を返し、nullの場合だけ右辺を評価します。
10-2. null合体代入演算子「??=」
??= は、左辺がnullの場合だけ右辺の値を代入する演算子です。
C#string? name = null;
name ??= "未設定";
Console.WriteLine(name); // 未設定
すでに値が入っている場合は、代入されません。
C#string? name = "山田";
name ??= "未設定";
Console.WriteLine(name); // 山田
初期値を設定したいときに便利です。
10-3. null条件演算子「?.」
?. は、左辺がnullでなければメンバーにアクセスし、nullなら結果としてnullを返します。
C#string? name = null;
int? length = name?.Length;
Console.WriteLine(length); // 空の出力
通常、name.Length と書くと、name がnullの場合に NullReferenceException が発生します。しかし、name?.Length と書けば、name がnullのときは例外ではなくnullになります。
C#のnull条件演算子 ?. と ?[] は、対象がnullでない場合だけメンバーアクセスや要素アクセスを行い、nullの場合はnullを返します。
10-4. null許容型と演算子の関係
C#では、値型に ? を付けるとnullを許容できます。
C#int? age = null;
通常、int にはnullを入れられません。
C#int age = null; // エラー
しかし、int? にするとnullを入れられます。
C#int? age = null;
null許容型では、?? を使って初期値を設定することがよくあります。
C#int? age = null;
int displayAge = age ?? 0;
Console.WriteLine(displayAge); // 0
10-5. NullReferenceExceptionを防ぐ使い方
NullReferenceException は、nullのオブジェクトにアクセスしようとしたときに発生するエラーです。
C#string? name = null;
// int length = name.Length; // NullReferenceExceptionの可能性
?. と ?? を組み合わせると、安全に値を取り出せます。
C#string? name = null;
int length = name?.Length ?? 0;
Console.WriteLine(length); // 0
このコードでは、name がnullなら name?.Length がnullになり、?? 0 によって 0 が使われます。
実務では、nullチェックを忘れるとエラーの原因になります。?.、??、??= は、C#演算子の中でも特に重要です。
11. 型チェック・型変換で使う演算子
C#では、オブジェクトの型を確認したり、別の型として扱ったりするための演算子があります。
11-1. 型を判定する「is」
is は、値が指定した型やパターンに一致するかどうかを判定します。
C#object value = "こんにちは";
if (value is string)
{
Console.WriteLine("文字列です");
}
また、型判定と変数宣言を同時に行うこともできます。
C#object value = "こんにちは";
if (value is string text)
{
Console.WriteLine(text.Length);
}
このコードでは、value が string なら、text という変数として使えます。is 演算子は、式が指定したパターンに一致すると true を返します。
11-2. 安全に型変換する「as」
as は、安全に型変換を行う演算子です。変換できない場合は例外ではなくnullを返します。
C#object value = "C#";
string? text = value as string;
Console.WriteLine(text); // C#
変換できない場合はnullになります。
C#object value = 123;
string? text = value as string;
Console.WriteLine(text == null); // True
as は参照型やnull許容型への変換で使います。キャスト式と違い、変換できない場合に例外をスローせずnullを返します。
11-3. キャスト演算子「()」
キャスト演算子は、値を別の型に変換するときに使います。
C#double number = 10.5;
int result = (int)number;
Console.WriteLine(result); // 10
この例では、double を int に変換しています。小数部分は切り捨てられます。
ただし、無効なキャストを行うと例外が発生します。
C#object value = "C#";
// int number = (int)value; // InvalidCastException
安全に変換したい場合は、is や as を使うとよいでしょう。
11-4. typeof演算子の使い方
typeof は、型そのものの情報を取得する演算子です。
C#Type type = typeof(string);
Console.WriteLine(type.Name); // String
リフレクション、属性、型情報の比較などで使われます。
C#if (typeof(string) == typeof(string))
{
Console.WriteLine("同じ型です");
}
初心者のうちは使用頻度は高くありませんが、フレームワークやライブラリを使うときに見かけることがあります。
11-5. 型変換でエラーが起きるケース
型変換でよくあるエラーは、変換できない型を無理にキャストすることです。
C#object value = "123";
// int number = (int)value; // エラー
文字列 "123" は見た目は数字ですが、型は string です。int に変換したい場合は、int.Parse や int.TryParse を使います。
C#string text = "123";
if (int.TryParse(text, out int number))
{
Console.WriteLine(number + 10); // 133
}
型変換では、「見た目」ではなく「実際の型」を意識することが重要です。
12. その他のC#でよく使う演算子
C#には、計算や比較以外にもよく使う演算子があります。ここでは、実務でも登場しやすい演算子を紹介します。
12-1. メンバーアクセス演算子「.」
. は、オブジェクトのメンバーにアクセスするための演算子です。
C#string text = "Hello";
Console.WriteLine(text.Length); // 5
この例では、text.Length によって文字列の長さを取得しています。
メソッドを呼び出すときにも使います。
C#Console.WriteLine(text.ToUpper()); // HELLO
12-2. インデックス演算子「[]」
[] は、配列やリストなどの要素にアクセスするために使います。
C#int[] numbers = { 10, 20, 30 };
Console.WriteLine(numbers[0]); // 10
Console.WriteLine(numbers[1]); // 20
C#のインデックスは0から始まります。最初の要素は [0] です。
リストでも使えます。
C#List<string> names = new List<string> { "田中", "佐藤", "鈴木" };
Console.WriteLine(names[0]); // 田中
12-3. ラムダ演算子「=>」
=> は、ラムダ式や式形式メンバーで使う演算子です。
C#Func<int, int> square = x => x * x;
Console.WriteLine(square(5)); // 25
この例では、x => x * x がラムダ式です。x を受け取り、x * x を返します。
LINQでもよく使われます。
C#int[] numbers = { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(x => x % 2 == 0);
foreach (int number in evenNumbers)
{
Console.WriteLine(number);
}
C#の => 演算子は、ラムダ式では左側のパラメーターと右側の処理本体を区切るために使われ、式形式メンバーでも使われます。
12-4. nameof演算子
nameof は、変数名、型名、メソッド名などを文字列として取得する演算子です。
C#string name = "田中";
Console.WriteLine(nameof(name)); // name
エラーメッセージや例外処理でよく使われます。
C#void SetName(string name)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
}
文字列を直接 "name" と書くよりも、nameof(name) を使う方が安全です。変数名を変更したときにも、IDEのリファクタリング機能で追従しやすくなります。
12-5. new演算子
new は、クラスや配列などのインスタンスを作成するために使います。
C#Person person = new Person();
配列を作るときにも使います。
C#int[] numbers = new int[3];
リストを作るときにも使います。
C#List<string> names = new List<string>();
C#では、オブジェクトを作成するときに new を使う場面が多くあります。
12-6. await演算子
await は、非同期処理の完了を待つために使う演算子です。
C#string result = await GetDataAsync();
await は、時間がかかる処理を待ちながら、アプリケーション全体を止めないようにするために使われます。
たとえば、Web APIからデータを取得する処理、ファイルを読み込む処理、データベースにアクセスする処理などで使われます。
C#async Task<string> GetMessageAsync()
{
await Task.Delay(1000);
return "完了しました";
}
await を使うメソッドには、通常 async を付けます。
12-7. switch式で使う演算子
C#では、switch 式を使って条件に応じた値を返せます。
C#int score = 85;
string grade = score switch
{
>= 90 => "A",
>= 80 => "B",
>= 70 => "C",
_ => "D"
};
Console.WriteLine(grade); // B
この例では、score の値に応じて成績を返しています。
=> は、switch式でも条件と結果を結びつけるために使われます。
C#string message = grade switch
{
"A" => "とても良いです",
"B" => "良いです",
"C" => "普通です",
_ => "がんばりましょう"
};
switch式は、複数の条件に応じて値を返したいときに便利です。
13. C#演算子の優先順位と結合規則
C#演算子には、どの演算子から先に処理されるかを決める「優先順位」があります。また、同じ優先順位の演算子をどの方向から処理するかを決める「結合規則」もあります。
13-1. 演算子の優先順位とは
演算子の優先順位とは、複数の演算子が同じ式に登場したときに、どの演算子を先に計算するかを決めるルールです。
C#int result = 2 + 3 * 4;
Console.WriteLine(result); // 14
このコードでは、+ より * の優先順位が高いため、先に 3 * 4 が計算されます。
そのため、結果は次のようになります。
2 + 12 = 14
もし足し算を先に行いたい場合は、丸括弧を使います。
C#int result = (2 + 3) * 4;
Console.WriteLine(result); // 20
13-2. 優先順位が高い演算子・低い演算子
一般的によく使う演算子では、次のような順序で優先順位が決まります。
| 優先順位 | 演算子の例 |
|---|---|
| 高い | ()、.、[] |
++、--、! | |
*、/、% | |
+、- | |
<、>、<=、>= | |
==、!= | |
&& | |
| ` | |
?? | |
?: | |
| 低い | =、+=、-= |
すべてを暗記する必要はありません。迷ったら丸括弧 () を使って、処理順を明確にするのがおすすめです。
13-3. 結合規則とは
結合規則とは、同じ優先順位の演算子が並んだときに、どちらの方向から処理するかを決めるルールです。
多くの二項演算子は左から右に評価されます。
C#int result = 10 - 3 - 2;
Console.WriteLine(result); // 5
このコードは次のように評価されます。
C#(10 - 3) - 2
一方、代入演算子は右から左に結合します。
C#int a;
int b;
a = b = 10;
Console.WriteLine(a); // 10
Console.WriteLine(b); // 10
C#では、代入演算子、null合体演算子、ラムダ、条件演算子 ?: は右結合で、それ以外の多くの二項演算子は左結合です。
13-4. 丸括弧「()」で処理順を明確にする方法
演算子の優先順位に迷ったら、丸括弧を使いましょう。
C#int result = 2 + 3 * 4;
Console.WriteLine(result); // 14
このコードは正しくても、初心者には少し読みにくい場合があります。
C#int result = 2 + (3 * 4);
Console.WriteLine(result); // 14
丸括弧を付けると、どの処理が先に行われるかが明確になります。
条件式でも同じです。
C#if ((age >= 18 && hasTicket) || isStaff)
{
Console.WriteLine("入場できます");
}
丸括弧を使うことで、条件のまとまりがわかりやすくなります。
13-5. 優先順位で結果が変わるサンプルコード
次のコードを見てください。
C#int result1 = 2 + 3 * 4;
int result2 = (2 + 3) * 4;
Console.WriteLine(result1); // 14
Console.WriteLine(result2); // 20
同じ数字と演算子を使っていても、丸括弧の有無で結果が変わります。
論理演算子でも同じです。
C#bool result1 = true || false && false;
bool result2 = (true || false) && false;
Console.WriteLine(result1); // True
Console.WriteLine(result2); // False
&& は || より優先順位が高いため、result1 では先に false && false が評価されます。
演算子の優先順位を完全に暗記するよりも、読みやすさのために丸括弧を使う習慣をつける方が実務では役立ちます。
14. C#演算子の使い方でよくある間違い
C#演算子は便利ですが、初心者が間違えやすいポイントもあります。ここでは、特に注意したい間違いをまとめます。
14-1. 「=」と「==」を間違える
= は代入、== は比較です。
C#int x = 10; // 代入
if (x == 10) // 比較
{
Console.WriteLine("10です");
}
「等しいかどうか」を調べたいときは == を使います。
14-2. 整数の割り算で小数にならない
整数同士の割り算では、小数部分が切り捨てられます。
C#int result = 5 / 2;
Console.WriteLine(result); // 2
小数が必要な場合は、double や decimal を使います。
C#double result = 5.0 / 2;
Console.WriteLine(result); // 2.5
金額計算では、誤差を避けるために decimal を使うことが多いです。
C#decimal price = 1000m;
decimal taxRate = 0.1m;
decimal tax = price * taxRate;
14-3. nullチェックを忘れる
nullの可能性がある変数に対して、そのままメンバーアクセスするとエラーになることがあります。
C#string? name = null;
// Console.WriteLine(name.Length); // 危険
null条件演算子を使うと安全です。
C#Console.WriteLine(name?.Length);
既定値を使いたい場合は、?? を組み合わせます。
C#int length = name?.Length ?? 0;
14-4. 前置・後置インクリメントを混同する
++x と x++ は、単独で使うと似ていますが、式の中では結果が変わります。
C#int x = 1;
int a = x++;
Console.WriteLine(a); // 1
Console.WriteLine(x); // 2
C#int y = 1;
int b = ++y;
Console.WriteLine(b); // 2
Console.WriteLine(y); // 2
初心者のうちは、インクリメントは単独の行で使うと安全です。
14-5. 論理演算子とビット演算子を混同する
&& と &、|| と | は似ていますが、意味が異なります。
C#bool a = true;
bool b = false;
Console.WriteLine(a && b); // False
Console.WriteLine(a || b); // True
&& と || は短絡評価を行います。
一方、& と | はbool値にも使えますが、右辺も評価されます。また、整数に使うとビット演算になります。
C#int x = 5;
int y = 3;
Console.WriteLine(x & y); // 1
Console.WriteLine(x | y); // 7
条件式では、通常 && と || を使うと覚えておきましょう。
14-6. 演算子の優先順位を誤解する
演算子の優先順位を誤解すると、意図しない結果になります。
C#int result = 2 + 3 * 4;
Console.WriteLine(result); // 14
足し算を先にしたい場合は、丸括弧を使います。
C#int result = (2 + 3) * 4;
Console.WriteLine(result); // 20
複雑な式では、優先順位に頼りすぎず、丸括弧で明確にすることが大切です。
15. C#演算子を覚えるための学習手順
C#演算子は数が多いため、最初からすべてを覚えようとすると大変です。初心者は、よく使う演算子から順番に覚えるのがおすすめです。
15-1. まず覚えるべき基本演算子
最初に覚えるべきなのは、次の演算子です。
C#+ - * / %
= += -=
== != > < >= <=
これらは、計算、代入、比較で頻繁に使います。
たとえば、次のコードを理解できれば、基本的な演算子はかなり身についています。
C#int price = 1000;
int count = 2;
int total = price * count;
if (total >= 2000)
{
Console.WriteLine("送料無料です");
}
15-2. if文・for文と一緒に覚える演算子
次に、if文やfor文と一緒に使う演算子を覚えましょう。
C#&& || !
++ --
if文では論理演算子を使います。
C#if (age >= 18 && hasTicket)
{
Console.WriteLine("入場できます");
}
for文ではインクリメント演算子を使います。
C#for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
演算子だけを単独で覚えるよりも、制御構文と一緒に学ぶ方が理解しやすいです。
15-3. null関連演算子は実務で重要
実務では、null関連演算子がとても重要です。
C#?? ??= ?.
たとえば、次のように使います。
C#string? name = GetName();
string displayName = name ?? "未設定";
nullチェックを簡潔に書けるため、C#の実務コードでは頻繁に登場します。
C#int length = name?.Length ?? 0;
NullReferenceException を防ぐためにも、null関連演算子は早めに覚えておくと役立ちます。
15-4. ビット演算子は必要になったときに学べばよい
ビット演算子は、初心者が最初に深く学ぶ必要はありません。
C#& | ^ ~ << >>
これらは、フラグ管理、低レベル処理、特殊な最適化などで使われます。
通常のWebアプリ、業務アプリ、コンソールアプリを学んでいる段階では、使用頻度はそれほど高くありません。必要になったときに、2進数の考え方と一緒に学べば十分です。
15-5. サンプルコードを書いて理解を深める
C#演算子は、読むだけではなかなか身につきません。実際にコードを書いて動かすことが大切です。
C#int a = 10;
int b = 3;
Console.WriteLine(a + b);
Console.WriteLine(a - b);
Console.WriteLine(a * b);
Console.WriteLine(a / b);
Console.WriteLine(a % b);
次に、条件分岐でも使ってみましょう。
C#int score = 75;
if (score >= 60)
{
Console.WriteLine("合格");
}
else
{
Console.WriteLine("不合格");
}
さらに、論理演算子も試してみます。
C#int age = 20;
bool hasTicket = true;
if (age >= 18 && hasTicket)
{
Console.WriteLine("入場できます");
}
演算子は、書いて、実行して、結果を確認することで理解が深まります。
16. C#演算子に関するよくある質問
最後に、C#演算子に関するよくある質問をまとめます。
16-1. C#で「==」と「Equals」の違いは?
== は演算子、Equals はメソッドです。
C#string a = "C#";
string b = "C#";
Console.WriteLine(a == b); // True
Console.WriteLine(a.Equals(b)); // True
文字列の場合、どちらも内容が等しいかを比較できます。
ただし、クラスによっては == と Equals の動作が異なる場合があります。自作クラスでは、== をオーバーロードしていない限り、参照が同じかどうかを見る動作になることがあります。
C#Person p1 = new Person();
Person p2 = new Person();
Console.WriteLine(p1 == p2); // 通常はFalse
値の等価性を比較したい場合は、型ごとの仕様を確認することが大切です。
16-2. C#で「&&」と「&」の違いは?
&& は条件付き論理ANDで、短絡評価を行います。
C#string? name = null;
if (name != null && name.Length > 0)
{
Console.WriteLine(name);
}
この場合、name != null が false なら、name.Length > 0 は評価されません。
一方、& はbool値に対して使うと両方の条件を評価します。また、整数に対して使うとビットANDになります。
C#bool a = true;
bool b = false;
Console.WriteLine(a & b); // False
通常の条件分岐では、&& を使うことが多いです。
16-3. C#で「??」はどんなときに使う?
?? は、値がnullだった場合に代わりの値を使いたいときに使います。
C#string? name = null;
string displayName = name ?? "ゲスト";
Console.WriteLine(displayName); // ゲスト
nullチェックを短く書けるため、実務でもよく使われます。
C#int length = name?.Length ?? 0;
このように、?. と組み合わせて使うことも多いです。
16-4. C#で「=>」は何を意味する?
=> は、ラムダ式や式形式メンバーで使います。
C#Func<int, int> doubleValue = x => x * 2;
Console.WriteLine(doubleValue(3)); // 6
左側に引数、右側に処理内容を書きます。
メソッドを短く書くときにも使えます。
C#int Square(int x) => x * x;
LINQでは特によく登場します。
C#var results = numbers.Where(x => x > 10);
=> は「左の値を使って右の処理を行う」とイメージすると理解しやすいです。
16-5. C#で演算子の優先順位はすべて覚える必要がある?
すべてを暗記する必要はありません。
よく使う優先順位として、次の流れを押さえておけば十分です。
() が最優先
* / % は + - より先
比較演算子は計算のあと
&& は || より先
代入は最後
迷った場合は、丸括弧を使いましょう。
C#int result = (2 + 3) * 4;
条件式でも、丸括弧を使うと読みやすくなります。
C#if ((age >= 18 && hasTicket) || isStaff)
{
Console.WriteLine("入場できます");
}
演算子の優先順位を完璧に覚えるよりも、読みやすく安全なコードを書くことが大切です。
まとめ
C#演算子は、計算、代入、比較、条件判定、nullチェック、型変換など、プログラムを書くうえで欠かせない基本文法です。
初心者が最初に覚えるべきなのは、算術演算子、代入演算子、比較演算子、論理演算子です。
C#+ - * / %
= += -=
== != > < >= <=
&& || !
これらを理解すれば、if文やfor文を使った基本的なプログラムを書けるようになります。
次に、実務でよく使うnull関連演算子を覚えましょう。
C#?? ??= ?.
これらは、NullReferenceException を防ぎ、安全で読みやすいコードを書くために役立ちます。
さらに、型チェックで使う is、as、キャスト演算子、ラムダ式で使う =>、非同期処理で使う await などを学ぶと、C#で書けるコードの幅が広がります。
C#演算子は数が多いため、最初からすべてを暗記する必要はありません。まずは基本演算子を使ったサンプルコードを書き、if文、for文、nullチェック、LINQなどの学習と合わせて少しずつ理解していきましょう。

