メソッドのオーバーロードとは
C#のクラス設計において、同じ名前を持ちながら、引数(パラメータ)の構成が異なるメソッドを複数定義する技術を「メソッドのオーバーロード(Overloading)」と呼びます。
例えば、Console.WriteLine()メソッドは、WriteLine(int value)やWriteLine(string value)、WriteLine(bool value)など、さまざまな型の引数を受け取ることができますが、呼び出し側はすべてWriteLineという同じ名前で利用できます。
メソッドをオーバーロードすることで、クラスの利用者が異なるパターンのデータ(引数)を渡した場合でも、同じメソッド名で直感的に操作できるようになり、APIの利便性が向上します。
オーバーロードのルール(メソッドのシグネチャ)
C#のコンパイラは、メソッド名が同じでも、その「シグネチャ」が異なれば、それらを別のメソッドとして区別します。
メソッドのシグネチャ(署名)とは、「メソッド名」と「引数のリスト(数・型・順序)」の組み合わせのことです。
オーバーロードが成立する条件:
- 引数の数が異なる(例:
Log(string)とLog(string, string)) - 引数の型が異なる(例:
Log(string)とLog(Exception)) - 引数の順序が異なる(例:
Log(string, int)とLog(int, string))
重要な注意点: 戻り値の型(voidやintなど)は、シグネチャの一部とはみなされません。 したがって、戻り値の型だけが異なる同名メソッドを定義することはできず、コンパイルエラーとなります。
C#
// コンパイルエラーになる例
public void Calculate() { ... }
public int Calculate() { ... } // 戻り値が違うだけではNG
オーバーロードのコード例
ここでは、SystemLoggerというロギングクラスを例に、Logという名前のメソッドを3つの異なるシグネチャでオーバーロードします。
Log(string message): 単純なメッセージをログに記録Log(string message, string severity): メッセージと重要度を記録Log(Exception ex): 例外オブジェクトを受け取り、エラーとして記録
SystemLogger クラスの定義
using System;
/// <summary>
/// ログ出力機能を提供するクラス
/// </summary>
public class SystemLogger
{
// ログレベルの定数(例)
private const string DefaultSeverity = "Info";
private const string ErrorSeverity = "Error";
/// <summary>
/// オーバーロード 1: メッセージのみを受け取る
/// </summary>
/// <param name="message">ログに出力するメッセージ</param>
public void Log(string message)
{
// 内部でオーバーロード 2 を呼び出し、デフォルトの重要度 "Info" を渡す
// このように、オーバーロードが別のオーバーロードを呼び出す設計は一般的です。
this.Log(message, DefaultSeverity);
}
/// <summary>
/// オーバーロード 2: メッセージと重要度を受け取る
/// (シグネチャが Log(string) とは異なる)
/// </summary>
/// <param name="message">メッセージ</param>
/// <param name="severity">重要度 (例: "Warning", "Error")</param>
public void Log(string message, string severity)
{
// 実際のログ出力処理(ここではコンソールに出力)
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] [{severity.ToUpper()}] {message}");
}
/// <summary>
/// オーバーロード 3: Exception オブジェクトを受け取る
/// (シグネチャが Log(string) や Log(string, string) とは異なる)
/// </summary>
/// <param name="ex">ログに出力する例外オブジェクト</param>
public void Log(Exception ex)
{
// 内部でオーバーロード 2 を呼び出し、例外メッセージと "Error" を渡す
this.Log(ex.Message, ErrorSeverity);
}
}
オーバーロードされたメソッドの呼び出し
呼び出し側は、渡す引数の構成(数や型)を変えるだけで、同じLogという名前のメソッドを呼び出すことができます。C#コンパイラは、渡された引数に最も一致するシグネチャを持つオーバーロードを自動的に選択します。
using System;
public class Program
{
public static void Main()
{
var logger = new SystemLogger();
Console.WriteLine("--- メソッドのオーバーロード呼び出し ---");
// 1. Log(string) が呼び出される
logger.Log("アプリケーションが起動しました。");
// 2. Log(string, string) が呼び出される
logger.Log("データベース接続に失敗しました。", "Warning");
// 3. Log(Exception) が呼び出される
try
{
// 意図的に例外を発生させる
string test = null;
test.ToUpper();
}
catch (NullReferenceException ex)
{
logger.Log(ex);
}
}
}
出力結果(時刻は実行時に依存):
--- メソッドのオーバーロード呼び出し ---
[16:45:01] [INFO] アプリケーションが起動しました。
[16:45:01] [WARNING] データベース接続に失敗しました。
[16:45:01] [ERROR] Object reference not set to an instance of an object.
まとめ
メソッドのオーバーロードは、C#においてクラスの利便性を高めるための基本的な機能です。
- 同じメソッド名で、**異なる引数の構成(数・型・順序)**を持つメソッドを複数定義できます。
- 呼び出し側は、引数の渡し方を変えるだけで、適切なメソッドが自動的に選択されます。
Console.WriteLine()のように、さまざまなデータ型に対応する同名のメソッドを提供することで、APIを直感的に利用できるようにします。
