C#演算子完全ガイド:比較・Nullの基礎からオーバーロード・優先順位などの応用まで徹底解説のカバー画像

C#演算子完全ガイド:比較・Nullの基礎からオーバーロード・優先順位などの応用まで徹底解説

公開日:2025/03/21最終更新日:2025/03/22

C#は、Web アプリケーション、デスクトップアプリケーション、ゲーム開発(Unity)、モバイルアプリケーション(Xamarin)など、幅広い分野で使用されているプログラミング言語です。


C#には、プログラムの処理を行うためにさまざまな演算子が用意されています。演算子とはプログラムの基本となる計算や条件分岐、論理判断などを実行するための記号であり、これらを適切に使いこなすことでより効率的で読みやすいコードを記述できます。


この記事では、C#で使用できる様々な演算子について、演算子の種類、使い方、優先順位、オーバーロードまで網羅的に解説します。


C#を学び始めた初心者からより深く理解したい中級者までC#の演算子を体系的に学ぶことができる内容となっているため、C#プログラミングのスキルアップに役立ててください。

1. C#の主要な演算子一覧

C# にはさまざまな種類の演算子があります。それぞれの演算子は、特定の目的のために設計されており、適切に使いこなすことで、効率的で読みやすいコードを実装できます。


ここではC#の主要な演算子を以下の4種類に分けて解説します。

  • 算術演算子

  • 比較演算子

  • 論理演算子

  • ビット演算子

算術演算子(+, -, *, /, %):計算処理の基本と余り(パーセント)の活用

算術演算子は数値計算を行うために使用されます。


主なものは以下のとおりです。

演算子

説明

+

2つの数値を足し合わせます

-

2つの数値の差を計算します

*

2つの数値を掛け合わせます

/

2つの数値を割ります

%

2つの数値を割った余りを計算します

コードの実装例は以下のとおりです。

int a = 10;

int b = 3;


int sum = a + b;        // 加算: 13

int difference = a - b; // 減算: 7

int product = a * b;    // 乗算: 30

int quotient = a / b;   // 除算: 3(整数同士の除算は小数点以下切り捨て)

int remainder = a % b;  // 余り: 1

特に % 演算子は割り算の余りを求める際に利用され、偶数・奇数判定や周期的な処理などで活用されます。

// 偶数/奇数の判定
int number = 10; // 判定する数値を設定

bool isEven = (number % 2 == 0);


// 時計の針のように0から11までの値を循環させる

int currentHour = 10; // 現在の時間

int hoursToAdd = 5; // 追加する時間

int hour = (currentHour + hoursToAdd) % 12;

余り演算子はパーセント記号(%)を使用しますが、割合を求める百分率計算とは異なることに注意しましょう。

比較演算子(==, !=, <, >, <=, >=):条件分岐

比較演算子は、2つの値を比較した結果のブール値(true/false)を返します。主に条件分岐で使われます。


比較演算子を以下に示します。

演算子

説明

==

2つの値が等しい場合に true を返します

!=

2つの値が等しくない場合に true を返します。

<

左側の値が右側の値より小さい場合に true を返します。

>

左側の値が右側の値より大きい場合に true を返します。

<=

左側の値が右側の値以下の場合に true を返します。

>=

左側の値が右側の値以上の場合に true を返します。

使い方の例は以下のとおりです。

int x = 5;

int y = 10;


bool isEqual = (x == y);      // 等しい: false

bool isNotEqual = (x != y);   // 等しくない: true

bool isLess = (x < y);        // より小さい: true

bool isGreater = (x > y);     // より大きい: false

bool isLessOrEqual = (x <= y);    // 以下: true

bool isGreaterOrEqual = (x >= y); // 以上: false

比較演算子は、if文やwhile文などの条件分岐でよく使われます。

int age = 20; // 年齢を定義
if (age >= 18)

{

    Console.WriteLine("成人です");

}

else

{

    Console.WriteLine("未成年です");

}

なお、参照型(クラスなど)の場合、== 演算子はデフォルトでオブジェクトの参照が同じかどうかを比較します。ただし、文字列型の場合は内容を比較する特別な扱いが適用されます。


== 演算子によるオブジェクト参照や文字列比較の例は以下になります。

string str1 = "hello";

string str2 = "hello";

string str3 = string.Copy(str1);


// 文字列の場合は内容を比較(特別な扱い)

bool strEqual = (str1 == str2); // true


// カスタムクラスの場合はデフォルトでは参照を比較

MyClass obj1 = new MyClass();

MyClass obj2 = new MyClass();

bool objEqual = (obj1 == obj2); // false(異なるインスタンス)

オブジェクトの内容が同じかどうかを比較するには、Equals メソッドをオーバーライドするか、== 演算子をオーバーロードしましょう。

論理演算子(&, |, &&, ||, !):複雑な条件式を記述

論理演算子は、複数の条件式を組み合わせて複雑な条件判定を行うときに利用します。

演算子

説明

&

2つの条件が両方とも true の場合に true を返します。

|

2つの条件のいずれかが true の場合に true を返します。

&&

左側の条件が true の場合にのみ、右側の条件を評価します。

||

左側の条件が false の場合にのみ、右側の条件を評価します。

!

条件を反転します。true を false に、false を true にします。

論理演算子の使用例は以下のとおりです。

bool isStudent = true;

int age = 20;


if (isStudent && age < 25) {

    Console.WriteLine("学生割引が適用されます。");

}


if (age < 18 || age >= 65) {

    Console.WriteLine("入場料が割引されます。");

}


if (!isStudent) {

    Console.WriteLine("一般料金が適用されます。");

}

&& と || は「短絡評価」を行います。つまり、左側の式の評価結果によって右側の式が評価されない場合があります。これにより、パフォーマンスが向上する可能性があります。

一方、& と | は常に両方の式を評価するため、右側の式に副作用がある場合は意図しない動作になる可能性がある点に注意が必要です。

ビット演算子(&, |, ^, ~, <<, >>):高度な制御とパフォーマンス向上

ビット演算子は、整数型のデータをビット単位で操作するために使用されます。主に、ハードウェア制御やパフォーマンスが重要な場面で活用されます。


ビット演算子の一覧は以下のとおりです。

演算子

説明

&

2つの値の対応するビットが両方とも 1 の場合に 1 を返します。

|

2つの値の対応するビットのいずれかが 1 の場合に 1 を返します。

^

2つの値の対応するビットが異なる場合に 1 を返します。

~

各ビットを反転します。(0 を 1 に、1 を 0 に)

<<

ビットを指定された数だけ左にシフトします。

>>

ビットを指定された数だけ右にシフトします。

使用例は以下のとおりです。

int x = 5; // 0101 (2進数)

int y = 3; // 0011 (2進数)


Console.WriteLine(x & y); // 0001 (10進数: 1)

Console.WriteLine(x | y); // 0111 (10進数: 7)

Console.WriteLine(x ^ y); // 0110 (10進数: 6)

Console.WriteLine(~x); // 11111111111111111111111111111010 (10進数: -6)

Console.WriteLine(x << 1); // 1010 (10進数: 10)

Console.WriteLine(x >> 1); // 0010 (10進数: 2)

ビット演算子は、フラグ管理やマスク処理、暗号化など、高度な制御を必要とする場面でよく使われます。またシフト演算は2のべき乗の乗算や除算を高速に行えるため、パフォーマンス向上にも貢献します。


関連記事

【C#】Listと配列との違いや初期化・削除・要素数取得・型指定なしの使い方を紹介

2.C#の特殊演算子:はてな演算子とnull関連演算子

C# には、null を安全に扱うための特殊な演算子があります。これらの演算子を使いこなすことでNullReferenceException の発生を防ぎ、より堅牢なコードを作成できます。


この章では、null 条件演算子 (?.) と null 合体演算子 (??) について詳しく解説します。

null条件演算子(?.)の使い方:安全なnullチェック

null 条件演算子 (?.) は、null の可能性があるオブジェクトのメンバに安全にアクセスするための演算子です。オブジェクトが null の場合、NullReferenceException を発生させる代わりに null を返します。


null 条件演算子 (?.) は、メンバアクセス(.)または要素アクセス([])を行う前に、左側のオペランド(オブジェクト)が null かどうかを評価します。


左側のオペランドが null ではない場合にのみメンバアクセスまたは要素アクセスを実行し、結果を返します。左側のオペランドが null の場合は、null を返します。これにより、NullReferenceException が発生する可能性を回避できます。


null条件演算子の使用例は以下のとおりです。

string name = null;

//name がnullの場合、例外が発生する

//Console.WriteLine(name.Length);


// ?.演算子を使用すると、nameがnullの場合、例外が発生せずにnullが返される

int? length = name?.Length;

Console.WriteLine(length); // null

null条件演算子は、プロパティチェーンやコレクション操作でも活用できます。

// プロパティチェーン

int? firstAddressZip = customer?.Address?.ZipCode;


// インデックスアクセス

string firstItem = stringList?[0];


// メソッド呼び出し

string upperName = name?.ToUpper();

この演算子を使うことで、従来の if 文による冗長な null チェックを減らし、コードをより簡潔かつ安全に記述できます。

null合体演算子(??)の使い方:nullの場合のデフォルト値を設定

null 合体演算子 (??) は、左側のオペランドが null と評価された場合に右側のオペランドの値を返し、null でない場合は左側のオペランドの値を返します。これにより、null の場合にデフォルト値を簡潔に設定できます。


null合体演算子の使用例は以下のとおりです。

result = operand1 ?? operand2;

null合体演算子は複数連結することも可能です。

// 複数連結の例

string displayName = firstName ?? middleName ?? lastName ?? "Anonymous";

また、null条件演算子とnull合体演算子を組み合わせることも可能です。

// nullチェックとデフォルト値の設定を一度に

int length = name?.Length ?? 0;


// 複雑なプロパティアクセスでのデフォルト値設定

string city = customer?.Address?.City ?? "Unknown City";

これらの演算子を活用することで、null値の処理がより簡潔になり、デフォルト値の設定が容易になります。

3.C#演算子のオーバーロード:カスタム型での演算子定義

C#では、ユーザ定義型のクラスや構造体に対して既存の演算子(+, -, *, / など)の動作を定義または再定義できます。これを演算子オーバーロードと呼びます。


演算子オーバーロードを使用することで、カスタム型のオブジェクトをより自然な形で操作できるようになり、コードの可読性が向上します。例えば、Vector クラスに対して + 演算子をオーバーロードすることで、v1 + v2 のように直感的にベクトル加算を記述できます。


この章では、C#演算子のオーバーロードについて、基本構文や使用例を紹介します。

演算子オーバーロードの基本構文:独自の型に演算子を適用

演算子オーバーロードは、operator キーワードを使用して定義します。オーバーロードする演算子の種類に応じて、適切なパラメータと戻り値の型を指定する必要があります。


演算子オーバーロードの基本構文は以下のとおりです。

public static 戻り値の型 operator 演算子 (パラメータ)

{

    // 演算子の処理

    return 結果;

}

演算子オーバーロードには以下のような制約がある点に注意しましょう。

  • オーバーロード可能な演算子は限られている(例: +, -, *, /, ==, !=, <, >など)

  • 演算子メソッドは必ずpublicとstaticでなければならない

  • 少なくとも一つのパラメータは、ユーザ定義型でなければならない

演算子オーバーロードの実装例

以下はボックス(Box)クラスにおける加算(+)演算子のオーバーロード例です。

using System;

class Box

{

    private double length, breadth, height;


    public void SetDimensions(double l, double b, double h)

    {

        length = l;

        breadth = b;

        height = h;

    }


    public double GetVolume() => length breadth height;


    // + 演算子のオーバーロード

    public static Box operator +(Box b1, Box b2)

    {

        return new Box

        {

            length = b1.length + b2.length,

            breadth = b1.breadth + b2.breadth,

            height = b1.height + b2.height

        };

    }

}


class Program

{

    static void Main()

    {

        Box box1 = new Box();

        box1.SetDimensions(6, 7, 5);


        Box box2 = new Box();

        box2.SetDimensions(12, 13, 10);


        Box box3 = box1 + box2; // + 演算子でボックスを加算


        Console.WriteLine($"Volume of Box3: {box3.GetVolume()}"); // 18*20*15=5400が表示される

    }

}

この例では、ボックス同士を加算し、それぞれの寸法を足し合わせた新しいボックスオブジェクトを作成しています。

4. C# 演算子 優先順位と結合規則

C#では、演算子の優先順位と結合順序が重要です。これらは、複数の演算子が含まれる式をどのように評価するかを定義します。


この章ではC#演算子の優先順位と結合規則について説明します。

C# 演算子の優先順位:基本概念

演算子の優先順位とは、複数の演算子が含まれる式においてどの演算子が先に評価されるかを決めるルールのことです。


例えば、算術式 3 + 4 5 では、乗算()は加算(+)よりも優先順位が高いため、まず 4 * 5 が計算され、その結果に 3 が加算されます。つまり、結果は 23 となります。


なお、優先順位が不明確な場合や明示的に評価順序を指定したい場合は、括弧(())を使用して意図を明確にすることが推奨されます。括弧を使用することでコードの可読性が向上し誤解を防ぐことができます。


括弧によって優先順位を変更する例は以下のとおりです。

// 括弧による優先順位の変更

int result2 = (3 + 4) 5;    // 3 + 4 = 7, 7 5 = 35

Console.WriteLine(result2);    // 出力: 35

上記の例の場合は先に括弧で囲まれた 3 + 4 が計算されてから、その結果に5を乗算します。

C# 演算子の結合順序:左結合性と右結合性の違い

結合規則とは、同じ優先順位を持つ演算子が連続して現れた場合にどの演算子から評価されるかを決定するルールのことです。


結合順序には、左結合性と右結合性の2種類があります。

  • 左結合性: 左から右へ評価されます。例えば、a - b - c という式は、(a - b) - c のように評価されます。

  • 右結合性: 右から左へ評価されます。例えば、a = b = c という式は、a = (b = c) のように評価されます。

左結合と右結合の例は以下のとおりです。

int result = 5 + 3 + 2; // 左結合

// (5 + 3) + 2 と評価される


int a, b = 0, c = 10;

a = b = c; // 右結合

// a = (b = c) と評価される

優先順位は異なる演算子間の評価順序で、結合順序は同じ優先順位の演算子が複数ある場合の評価順序だと覚えておきましょう。

C# 演算子 優先順位と結合順序の一覧表

C# の主要な演算子を優先順位と結合順序とともに一覧表にまとめました。表の上段が優先順位が高く下に行くほど優先順位が低くなります。

操作の種類

演算子

結合規則

括弧

() 

左から右

後置インクリメントなど

x++, x--

左から右

前置インクリメントなど

++x, --x, +x, -x, !x, ~x 

右から左

乗算、除算、剰余

x * y, x / y, x % y

左から右

加算、減算

x + y, x - y

左から右

ビットシフト

x << y, x >> y

左から右

比較

x < y, x > y, x <= y, x >= y

左から右

等価

x == y, x != y

左から右

ビット論理積

x & y

左から右

ビット排他的論理和

x ^ y

左から右

ビット論理和

x | y

左から右

条件論理積

x && y

左から右

条件論理和

x || y

左から右

この一覧表を参考にC#演算子の優先順位と結合規則を整理しましょう。


関連記事

C#とは?基本文法や特徴、メリット、開発分野まで初心者に必要な情報をわかりやすく解説

5.まとめ

C#の演算子はプログラミングにおいて基本となる重要な要素です。本記事では、C#で使用される様々な種類の演算子について詳しく解説しました。


C#には、算術演算子、比較演算子、論理演算子、ビット演算子といった基本的なものから、null 条件演算子や null 合体演算子などの特殊な演算子、さらには演算子オーバーロードまでさまざまな演算子があります。また、演算子の優先順位や結合規則を理解しておくのも重要です。


C# の演算子を正しく理解することで、複雑な処理を簡潔に記述できるようになり、コードの表現力が向上します。本記事で解説した内容を活用し、C#プログラミングのスキルを向上させましょう。


本記事が皆様にとって少しでもお役に立てますと幸いです。


「フリーランスボード」は、数多くのフリーランスエージェントが掲載するITフリーランスエンジニア・ITフリーランス向けの案件・求人を一括検索できるサイトです。


開発環境、職種、単価、稼働形態、稼働日数など様々な条件から、あなたに最適なフリーランス案件・求人を簡単に見つけることができます。

単価アップを目指す方や、自分の得意なスキルを活かせる案件に参画したい方は、ぜひ「フリーランスボード」をご利用ください。

無料で登録したらスカウトを待つだけ フリーランスの新しい仕事探しを始めよう

フルリモート案件を 無料登録した方限定で配信中

目次

1. C#の主要な演算子一覧

算術演算子(+, -, *, /, %):計算処理の基本と余り(パーセント)の活用

比較演算子(==, !=, <, >, <=, >=):条件分岐

論理演算子(&, |, &&, ||, !):複雑な条件式を記述

ビット演算子(&, |, ^, ~, <<, >>):高度な制御とパフォーマンス向上

2.C#の特殊演算子:はてな演算子とnull関連演算子

null条件演算子(?.)の使い方:安全なnullチェック

null合体演算子(??)の使い方:nullの場合のデフォルト値を設定

3.C#演算子のオーバーロード:カスタム型での演算子定義

演算子オーバーロードの基本構文:独自の型に演算子を適用

演算子オーバーロードの実装例

4. C# 演算子 優先順位と結合規則

C# 演算子の優先順位:基本概念

C# 演算子の結合順序:左結合性と右結合性の違い

C# 演算子 優先順位と結合順序の一覧表

5.まとめ