C#の関数(メソッド)とは?定義・呼び出し・引数・戻り値を初心者向けに解説

はじめに

C#でプログラムを作るうえで欠かせないのが、関数に相当する「メソッド」です。メソッドを使うと、複数の処理をひとまとまりにし、必要な場所から何度でも呼び出せます。

たとえば、画面にメッセージを表示する処理や、2つの数値を足し算する処理をメソッドとして定義しておけば、同じコードを繰り返し書く必要がありません。

この記事では、C#の関数(メソッド)について、次の内容を初心者向けに解説します。

  • メソッドの定義方法

  • メソッドの呼び出し方

  • 引数と戻り値の使い方

  • staticメソッドとインスタンスメソッドの違い

  • よく使う機能やエラーの対処法

基本的なサンプルコードを確認しながら、C#のメソッドを一つずつ理解していきましょう。

1. C#の関数(メソッド)とは?

1-1. C#では「関数」より「メソッド」と呼ぶのが一般的

一般的なプログラミング用語では、特定の処理をまとめたものを「関数」と呼びます。

C#では、処理をまとめたものが基本的にクラスや構造体などの型に属するため、「関数」ではなく「メソッド」と呼ぶのが一般的です。

たとえば、次のShowMessageがメソッドです。

C#
static void ShowMessage()
{
Console.WriteLine("こんにちは");
}

C#の学習中に「関数を作る」「関数を呼び出す」という説明を見かけることもありますが、多くの場合はメソッドを指しています。

そのため、C#においては「関数とメソッドはほぼ同じ意味で使われることがある」と考えつつ、正式な用語としてはメソッドを覚えておくとよいでしょう。

1-2. メソッドの役割は処理をひとまとまりにして再利用すること

メソッドの主な役割は、関連する処理をひとまとまりにして、必要な場所から再利用できるようにすることです。

たとえば、名前を受け取り、あいさつを表示する処理は次のように書けます。

C#
static void Greet(string name)
{
Console.WriteLine($"こんにちは、{name}さん");
}

定義したメソッドは、次のように呼び出します。

C#
Greet("田中");
Greet("鈴木");

実行結果は次のとおりです。

こんにちは、田中さん
こんにちは、鈴木さん

表示する名前は異なりますが、あいさつを組み立てる処理は共通です。このような共通処理をメソッドにまとめることで、コードを効率よく再利用できます。

1-3. メソッドを使うメリット

C#でメソッドを使う主なメリットは、次のとおりです。

  • 同じ処理を何度も書かずに済む

  • プログラムの構造がわかりやすくなる

  • 修正する場所を減らせる

  • 処理単位でテストしやすくなる

  • 複数人で開発するときに役割を分けやすくなる

たとえば、消費税込みの価格を求める計算を複数の場所に直接書いた場合、税率や計算方法が変わると、すべての場所を修正しなければなりません。

一方、計算処理をメソッドにまとめておけば、原則としてメソッドの中だけを修正すれば済みます。

C#
static decimal CalculateTaxIncludedPrice(decimal price, decimal taxRate)
{
return price * (1 + taxRate);
}

メソッドを適切に使うことは、読みやすく保守しやすいプログラムを作るための基本です。

1-4. メソッドとクラスの関係

C#のメソッドは、基本的にクラスや構造体などの型の中に定義します。

C#
class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}

この例では、Calculatorクラスの中にAddメソッドを定義しています。

従来のC#プログラムでは、エントリーポイントとなるMainメソッドもクラスの中に記述します。

C#
class Program
{
static void Main()
{
Console.WriteLine("プログラムを開始します");
}
}

新しいC#では、クラスやMainメソッドを省略できる「トップレベルステートメント」も利用できます。ただし、その場合でも、メソッドやクラスの考え方はC#を学ぶうえで重要です。

2. C#のメソッドの基本構文

2-1. メソッド定義の基本形

C#でメソッドを定義するときの基本形は、次のとおりです。

C#
アクセス修飾子 static 戻り値の型 メソッド名(引数リスト)
{
処理
}

具体例を見てみましょう。

C#
public static int Add(int a, int b)
{
return a + b;
}

それぞれの要素には次の意味があります。

  • public:アクセス修飾子

  • static:クラスそのものに属することを表す

  • int:戻り値の型

  • Add:メソッド名

  • int a, int b:引数リスト

  • { }の中:メソッドが実行する処理

  • return a + b;:計算結果を呼び出し元へ返す処理

すべてのメソッドにpublicstaticが必要なわけではありません。目的や呼び出し方に応じて指定します。

2-2. アクセス修飾子とは

アクセス修飾子は、そのメソッドをどこから呼び出せるかを指定するキーワードです。

初心者がよく使うアクセス修飾子には、次のようなものがあります。

  • public:クラスの外部から呼び出せる

  • private:同じクラスの中からだけ呼び出せる

  • protected:同じクラスや継承先のクラスから呼び出せる

  • internal:同じアセンブリ内から呼び出せる

たとえば、次のAddメソッドはpublicなので、Calculatorクラスの外部から呼び出せます。

C#
class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}

一方、外部に公開する必要がない内部処理には、privateを使います。

C#
class Calculator
{
private bool IsPositive(int number)
{
return number > 0;
}
}

クラスのメンバーにアクセス修飾子を書かなかった場合、通常はprivateとして扱われます。ただし、コードの意図を明確にするため、必要に応じてアクセス修飾子を明示するとよいでしょう。

2-3. 戻り値の型とは

戻り値の型は、メソッドが呼び出し元に返す値の種類を表します。

次のメソッドは、計算結果としてint型の値を返します。

C#
static int Add(int a, int b)
{
return a + b;
}

文字列を返す場合は、戻り値の型にstringを指定します。

C#
static string CreateMessage(string name)
{
return $"こんにちは、{name}さん";
}

戻り値がないメソッドでは、戻り値の型としてvoidを指定します。

C#
static void ShowMessage()
{
Console.WriteLine("メッセージを表示します");
}

戻り値の型と、returnで返す値の型は一致している必要があります。

2-4. メソッド名の付け方

メソッド名には、何をする処理なのかがわかる名前を付けましょう。

C#では、メソッド名を大文字で始めるPascalCaseを使うのが一般的です。

C#
CalculateTotal()
ShowMessage()
GetUserName()
SaveFile()

次のような意味のわかりにくい名前は避けたほうがよいでしょう。

C#
DoIt()
Method1()
Test()
Abc()

名前だけを見て処理内容を推測できるようにすると、コードが読みやすくなります。

また、メソッドは処理を実行するものなので、GetCreateCalculateShowSaveなど、動作を表す単語から始めると役割が伝わりやすくなります。

2-5. 引数リストとは

引数リストは、メソッドが外部から受け取る値を定義する部分です。

C#
static void Greet(string name)
{
Console.WriteLine($"こんにちは、{name}さん");
}

この例では、string nameが引数です。

複数の引数を受け取る場合は、カンマで区切ります。

C#
static int Add(int a, int b)
{
return a + b;
}

引数を受け取らない場合でも、メソッド名の後ろに丸括弧を書きます。

C#
static void ShowMessage()
{
Console.WriteLine("こんにちは");
}

2-6. メソッド本体に処理を書く

メソッドが実行する処理は、波括弧{ }の中に記述します。

C#
static void ShowProfile(string name, int age)
{
Console.WriteLine($"名前:{name}");
Console.WriteLine($"年齢:{age}歳");
}

メソッド本体には、変数宣言、計算、条件分岐、繰り返し処理、別のメソッドの呼び出しなど、さまざまな処理を書けます。

C#
static void CheckAge(int age)
{
if (age >= 18)
{
Console.WriteLine("成人です");
}
else
{
Console.WriteLine("未成年です");
}
}

ただし、1つのメソッドに多くの役割を詰め込みすぎると、コードが読みにくくなります。できるだけ「1つのメソッドには1つの役割」を意識しましょう。

3. C#でメソッドを定義する方法

3-1. 戻り値がないメソッドの定義

戻り値がないメソッドでは、戻り値の型にvoidを指定します。

C#
static void ShowGreeting()
{
Console.WriteLine("おはようございます");
}

このメソッドは画面に文字列を表示しますが、呼び出し元に値を返しません。

呼び出すときは、次のようにメソッド名と丸括弧を書きます。

C#
ShowGreeting();

画面表示やデータの保存など、処理を実行すること自体が目的である場合にvoidを使います。

3-2. 戻り値があるメソッドの定義

戻り値があるメソッドでは、返す値の型をメソッド名の前に指定し、return文で値を返します。

C#
static int GetAnswer()
{
return 42;
}

次のように、計算した結果を返すこともできます。

C#
static int Multiply(int a, int b)
{
return a * b;
}

戻り値は変数に代入したり、別の計算に使ったりできます。

C#
int result = Multiply(3, 4);
Console.WriteLine(result);

実行結果は12です。

3-3. 引数がないメソッドの定義

引数がないメソッドは、丸括弧の中を空にします。

C#
static string GetAppName()
{
return "サンプルアプリ";
}

呼び出し時にも、空の丸括弧を付けます。

C#
string appName = GetAppName();
Console.WriteLine(appName);

丸括弧を省略して、次のように書くことはできません。

C#
// 誤り
string appName = GetAppName;

3-4. 引数があるメソッドの定義

引数があるメソッドでは、丸括弧の中に「型」と「引数名」を指定します。

C#
static void ShowName(string name)
{
Console.WriteLine($"名前は{name}です");
}

呼び出すときは、引数に対応する値を渡します。

C#
ShowName("佐藤");

nameの型はstringなので、基本的には文字列を渡す必要があります。

3-5. 複数の引数を受け取るメソッドの定義

複数の引数を受け取る場合は、引数をカンマで区切ります。

C#
static void ShowUser(string name, int age)
{
Console.WriteLine($"{name}さんは{age}歳です");
}

呼び出すときは、定義した順番に値を渡します。

C#
ShowUser("山田", 25);

異なる型の引数も同時に使用できます。

C#
static void ShowProduct(string productName, decimal price, bool inStock)
{
Console.WriteLine($"商品名:{productName}");
Console.WriteLine($"価格:{price}円");
Console.WriteLine($"在庫あり:{inStock}");
}

4. C#でメソッドを呼び出す方法

4-1. メソッド呼び出しの基本形

メソッドを呼び出す基本形は、次のとおりです。

C#
メソッド名();

引数がある場合は、丸括弧の中に値を指定します。

C#
メソッド名(値1, 値2);

戻り値がある場合は、変数に代入できます。

C#
 変数名 = メソッド名();

メソッドの定義だけでは、通常、その処理は実行されません。必要な場所から呼び出して初めて処理が実行されます。

4-2. 引数なしメソッドを呼び出す

引数なしメソッドの定義と呼び出しを組み合わせると、次のようになります。

C#
class Program
{
static void Main()
{
ShowMessage();
}

static void ShowMessage()
{
Console.WriteLine("C#を学習中です");
}
}

MainメソッドからShowMessageメソッドを呼び出しています。

実行結果は次のとおりです。

C#を学習中です

4-3. 引数ありメソッドを呼び出す

引数ありメソッドを呼び出すときは、定義されている引数に合わせて値を渡します。

C#
class Program
{
static void Main()
{
Greet("高橋");
}

static void Greet(string name)
{
Console.WriteLine($"こんにちは、{name}さん");
}
}

この例では、"高橋"nameに渡されます。

変数を引数として渡すこともできます。

C#
string userName = "伊藤";
Greet(userName);

4-4. 戻り値を変数に代入する

戻り値があるメソッドを呼び出す場合は、その結果を変数に代入できます。

C#
static int Add(int a, int b)
{
return a + b;
}

呼び出し側は次のように書きます。

C#
int total = Add(10, 20);
Console.WriteLine(total);

メソッドの戻り値を、別のメソッドの引数として直接渡すこともできます。

C#
Console.WriteLine(Add(10, 20));

ただし、処理を確認しやすくしたい場合は、一度変数に代入すると読みやすくなります。

4-5. 同じメソッドを何度も呼び出す

メソッドは、必要な回数だけ呼び出せます。

C#
static void Greet(string name)
{
Console.WriteLine($"こんにちは、{name}さん");
}

Greet("田中");
Greet("鈴木");
Greet("佐藤");

繰り返し処理と組み合わせることもできます。

C#
string[] names = { "田中", "鈴木", "佐藤" };

foreach (string name in names)
{
Greet(name);
}

同じ処理を何度も実行する場面では、メソッド化することでコードの重複を減らせます。

5. 引数の使い方を初心者向けに解説

5-1. 引数とはメソッドに渡す値のこと

引数とは、メソッドに処理してもらうために渡す値です。

たとえば、次のメソッドは名前を受け取って、あいさつを表示します。

C#
static void Greet(string name)
{
Console.WriteLine($"こんにちは、{name}さん");
}

呼び出し時に渡す名前を変えることで、同じメソッドをさまざまな利用者に使えます。

C#
Greet("田中");
Greet("鈴木");

引数は、メソッドの外部から内部へデータを渡す入口と考えると理解しやすいでしょう。

5-2. 仮引数と実引数の違い

メソッドの引数には、「仮引数」と「実引数」という呼び方があります。

C#
static void Greet(string name)
{
Console.WriteLine($"こんにちは、{name}さん");
}

Greet("田中");

この例では、次のように区別します。

  • name:仮引数

  • "田中":実引数

仮引数は、メソッドを定義するときに受け取る値を表す変数です。実引数は、メソッドを呼び出すときに実際に渡す値です。

実引数として変数を渡すこともできます。

C#
string userName = "田中";
Greet(userName);

この場合、userNameの値が仮引数nameに渡されます。

5-3. 引数の型を指定する理由

C#は、変数や値の型を明確に扱う言語です。そのため、メソッドの引数にも型を指定します。

C#
static void ShowAge(int age)
{
Console.WriteLine($"{age}歳です");
}

ageint型なので、次の呼び出しは正しく動作します。

C#
ShowAge(20);

一方、文字列をそのまま渡すとエラーになります。

C#
// エラー
ShowAge("20");

文字列の"20"と整数の20は、見た目が似ていても異なる型です。

引数の型を指定することで、メソッドがどのようなデータを必要としているのかが明確になり、誤った値を渡すミスを防ぎやすくなります。

5-4. 複数の引数を使う方法

複数の値が必要な処理では、複数の引数を定義します。

C#
static int CalculateTotal(int price, int quantity)
{
return price * quantity;
}

呼び出すときは、引数の順番に注意しましょう。

C#
int total = CalculateTotal(500, 3);
Console.WriteLine(total);

この場合、price500quantity3が渡されるため、結果は1500になります。

引数の意味が似ている場合は、変数を使うとわかりやすくなります。

C#
int price = 500;
int quantity = 3;

int total = CalculateTotal(price, quantity);

5-5. 引数を使うと処理を柔軟にできる

引数を使わないメソッドでは、毎回同じデータに対して同じ処理を行います。

C#
static void Greet()
{
Console.WriteLine("こんにちは、田中さん");
}

引数を使えば、呼び出しごとに処理対象を変更できます。

C#
static void Greet(string name)
{
Console.WriteLine($"こんにちは、{name}さん");
}

さらに、あいさつの種類も引数にできます。

C#
static void Greet(string greeting, string name)
{
Console.WriteLine($"{greeting}、{name}さん");
}
C#
Greet("おはようございます", "田中");
Greet("こんばんは", "鈴木");

引数を適切に設計することで、1つのメソッドを幅広い場面で再利用できます。

6. 戻り値の使い方を初心者向けに解説

6-1. 戻り値とはメソッドから返される結果のこと

戻り値とは、メソッドが処理した結果として、呼び出し元へ返す値です。

C#
static int Add(int a, int b)
{
return a + b;
}

Addメソッドを呼び出すと、足し算の結果が戻り値として返されます。

C#
int result = Add(3, 5);

この場合、resultには8が代入されます。

引数がメソッドへの入力であり、戻り値がメソッドからの出力であると考えると理解しやすいでしょう。

6-2. return文の基本

return文は、メソッドから値を返すために使います。

C#
static int Square(int number)
{
return number * number;
}

returnが実行されると、基本的にはその時点でメソッドの処理が終了します。

C#
static string CheckNumber(int number)
{
if (number > 0)
{
return "正の数です";
}

return "0または負の数です";
}

numberが正の数であれば、最初のreturnでメソッドが終了します。正の数でなければ、最後のreturnが実行されます。

6-3. 戻り値の型とreturnする値を一致させる

メソッドで指定した戻り値の型と、returnで返す値の型は一致させる必要があります。

次のコードは正しい例です。

C#
static int GetNumber()
{
return 10;
}

次のコードは、戻り値の型が一致していないためエラーになります。

C#
static int GetNumber()
{
// エラー:string型をint型として返せない
return "10";
}

文字列を返したい場合は、戻り値の型もstringにします。

C#
static string GetNumberText()
{
return "10";
}

6-4. voidは戻り値がないことを表す

voidは、そのメソッドが値を返さないことを表します。

C#
static void ShowMessage()
{
Console.WriteLine("こんにちは");
}

voidメソッドでは、値を指定したreturnは使えません。

C#
static void ShowMessage()
{
// エラー
return "こんにちは";
}

ただし、値を付けないreturn;を使って、メソッドを途中で終了することはできます。

C#
static void ShowPositiveNumber(int number)
{
if (number <= 0)
{
return;
}

Console.WriteLine(number);
}

6-5. 戻り値を使うメソッドの具体例

税込価格を計算するメソッドを考えてみましょう。

C#
static decimal CalculateTaxIncludedPrice(decimal price, decimal taxRate)
{
return price * (1 + taxRate);
}

呼び出し側では、戻り値を受け取り、その後の処理に利用できます。

C#
decimal total = CalculateTaxIncludedPrice(1000m, 0.1m);

Console.WriteLine($"税込価格は{total}円です");

戻り値を利用すると、計算結果を表示するだけでなく、保存したり、別の計算に使ったりできます。

C#
decimal firstPrice = CalculateTaxIncludedPrice(1000m, 0.1m);
decimal secondPrice = CalculateTaxIncludedPrice(2000m, 0.1m);
decimal grandTotal = firstPrice + secondPrice;

7. staticメソッドとインスタンスメソッドの違い

7-1. staticメソッドとは

staticメソッドは、特定のオブジェクトではなく、クラスそのものに属するメソッドです。

C#
class Calculator
{
public static int Add(int a, int b)
{
return a + b;
}
}

staticメソッドは、通常、クラス名を使って呼び出します。

C#
int result = Calculator.Add(10, 20);

Calculatorクラスのオブジェクトを作らなくても呼び出せる点が特徴です。

Console.WriteLineも、Consoleクラスのstaticメソッドです。

C#
Console.WriteLine("こんにちは");

7-2. インスタンスメソッドとは

インスタンスメソッドは、クラスから作成したオブジェクトに属するメソッドです。

C#
class Person
{
public string Name { get; set; } = "";

public void Introduce()
{
Console.WriteLine($"私は{Name}です");
}
}

呼び出すには、まずnewを使ってインスタンスを作成します。

C#
Person person = new Person();
person.Name = "田中";
person.Introduce();

インスタンスごとに異なるデータを扱う処理には、インスタンスメソッドが適しています。

C#
Person firstPerson = new Person();
firstPerson.Name = "田中";

Person secondPerson = new Person();
secondPerson.Name = "鈴木";

firstPerson.Introduce();
secondPerson.Introduce();

7-3. Mainメソッドから呼び出すときの注意点

従来形式のMainメソッドは、一般的にstaticとして定義します。

C#
static void Main()
{
}

staticメソッドから、同じクラスのインスタンスメソッドを直接呼び出すことはできません。

C#
class Program
{
static void Main()
{
// エラー
ShowMessage();
}

void ShowMessage()
{
Console.WriteLine("こんにちは");
}
}

インスタンスメソッドを呼び出す場合は、オブジェクトを作成します。

C#
class Program
{
static void Main()
{
Program program = new Program();
program.ShowMessage();
}

void ShowMessage()
{
Console.WriteLine("こんにちは");
}
}

または、呼び出すメソッドをstaticにします。

C#
class Program
{
static void Main()
{
ShowMessage();
}

static void ShowMessage()
{
Console.WriteLine("こんにちは");
}
}

7-4. 初心者がまず理解すべき使い分け

初心者の段階では、次のように使い分けると理解しやすいでしょう。

  • オブジェクト固有のデータを使わない処理:staticメソッド

  • オブジェクトが持つデータを使う処理:インスタンスメソッド

たとえば、2つの数値を足し算する処理は、特定のオブジェクトの状態を必要としないため、staticメソッドにできます。

C#
public static int Add(int a, int b)
{
return a + b;
}

一方、人物の名前を使って自己紹介する処理は、各人物のデータに依存するため、インスタンスメソッドが適しています。

C#
public void Introduce()
{
Console.WriteLine($"私は{Name}です");
}

最初はstaticを付けた小さなメソッドから練習し、クラスとオブジェクトを学んだ後にインスタンスメソッドへ進むと理解しやすくなります。

8. C#のメソッドでよく使う機能

8-1. メソッドのオーバーロード

メソッドのオーバーロードとは、同じ名前で引数の数や型が異なるメソッドを複数定義する機能です。

C#
static int Add(int a, int b)
{
return a + b;
}

static double Add(double a, double b)
{
return a + b;
}

static int Add(int a, int b, int c)
{
return a + b + c;
}

呼び出し時に渡した引数の数や型によって、適切なメソッドが選ばれます。

C#
int result1 = Add(1, 2);
double result2 = Add(1.5, 2.5);
int result3 = Add(1, 2, 3);

戻り値の型だけを変えてオーバーロードすることはできません。引数の数、型、順序のいずれかを変える必要があります。

8-2. 省略可能な引数

引数に初期値を設定すると、その引数を省略できるようになります。

C#
static void Greet(string name, string greeting = "こんにちは")
{
Console.WriteLine($"{greeting}、{name}さん");
}

第2引数を省略すると、初期値の"こんにちは"が使われます。

C#
Greet("田中");

第2引数を指定することもできます。

C#
Greet("田中", "おはようございます");

省略可能な引数は、原則として必須の引数より後ろに配置します。

8-3. 名前付き引数

名前付き引数を使うと、引数名を指定して値を渡せます。

C#
static void ShowUser(string name, int age, string city)
{
Console.WriteLine($"{name}さん、{age}歳、{city}在住");
}

通常の呼び出しは次のとおりです。

C#
ShowUser("田中", 30, "東京");

名前付き引数を使うと、各値の意味が明確になります。

C#
ShowUser(name: "田中", age: 30, city: "東京");

引数の意味がわかりにくい場合や、複数の省略可能な引数を扱う場合に便利です。

8-4. ref引数とout引数

通常、値型の引数をメソッドに渡すと、値のコピーが渡されます。そのため、メソッド内で仮引数を変更しても、呼び出し元の変数は変わりません。

refを使うと、呼び出し元の変数そのものを参照して変更できます。

C#
static void DoubleValue(ref int number)
{
number *= 2;
}

呼び出すときにもrefを付けます。

C#
int value = 10;
DoubleValue(ref value);

Console.WriteLine(value);

実行結果は20です。refに渡す変数は、呼び出す前に値を代入しておく必要があります。

outは、メソッドから複数の値を受け取りたい場合などに使えます。

C#
static void GetSize(out int width, out int height)
{
width = 1920;
height = 1080;
}
C#
GetSize(out int width, out int height);

Console.WriteLine(width);
Console.WriteLine(height);

out引数は、メソッドの中で値を代入する必要があります。

実務では、複数の値を返す方法としてタプルや専用クラスを使うこともあります。初心者は、まず通常の引数と戻り値を理解してからrefoutを学ぶとよいでしょう。

8-5. ラムダ式やローカル関数との違い

C#には、通常のメソッド以外にも、処理をまとめる方法があります。

ラムダ式は、短い処理を値として扱いたい場合などに使います。

C#
Func<int, int, int> add = (a, b) => a + b;

int result = add(3, 5);

ローカル関数は、別のメソッドの中に定義する関数です。

C#
static void Main()
{
int Add(int a, int b)
{
return a + b;
}

Console.WriteLine(Add(3, 5));
}

主な違いは次のとおりです。

  • 通常のメソッド:クラスなどの型に属する

  • ローカル関数:特定のメソッドの内部だけで使う

  • ラムダ式:処理を変数に代入したり、別のメソッドに渡したりできる

初心者は、最初に通常のメソッドを理解することが重要です。ラムダ式やローカル関数は、その後に学ぶとよいでしょう。

9. C#のメソッドの具体例

9-1. 文字列を表示するメソッド

文字列を受け取り、画面に表示するメソッドです。

C#
static void ShowMessage(string message)
{
Console.WriteLine(message);
}

呼び出し例は次のとおりです。

C#
ShowMessage("C#のメソッドを学習しています");
ShowMessage("同じ処理を再利用できます");

表示する内容を引数として受け取るため、さまざまなメッセージに対応できます。

9-2. 2つの数値を足し算するメソッド

2つの整数を受け取り、足し算の結果を返すメソッドです。

C#
static int Add(int a, int b)
{
return a + b;
}

呼び出し例は次のとおりです。

C#
int result = Add(15, 25);

Console.WriteLine($"計算結果:{result}");

実行結果は次のとおりです。

計算結果:40

9-3. 条件分岐を使うメソッド

点数を受け取り、合否を判定するメソッドです。

C#
static string JudgeResult(int score)
{
if (score >= 60)
{
return "合格";
}

return "不合格";
}

呼び出し例は次のとおりです。

C#
string result = JudgeResult(75);

Console.WriteLine(result);

条件分岐の結果を戻り値として返すことで、呼び出し元が結果を自由に利用できます。

真偽値を返す設計も可能です。

C#
static bool IsPassed(int score)
{
return score >= 60;
}
C#
if (IsPassed(75))
{
Console.WriteLine("合格です");
}

9-4. 配列やリストを受け取るメソッド

メソッドの引数には、配列やリストも指定できます。

配列の合計を求めるメソッドは、次のように書けます。

C#
static int CalculateSum(int[] numbers)
{
int total = 0;

foreach (int number in numbers)
{
total += number;
}

return total;
}

呼び出し例は次のとおりです。

C#
int[] scores = { 80, 70, 90 };
int total = CalculateSum(scores);

Console.WriteLine(total);

List<string>を受け取るメソッドも定義できます。

C#
static void ShowNames(List<string> names)
{
foreach (string name in names)
{
Console.WriteLine(name);
}
}
C#
List<string> names = new List<string>
{
"田中",
"鈴木",
"佐藤"
};

ShowNames(names);

9-5. クラス内でメソッドを使う実践例

銀行口座を表す簡単なクラスを作ってみましょう。

C#
class BankAccount
{
public string OwnerName { get; }
public decimal Balance { get; private set; }

public BankAccount(string ownerName, decimal initialBalance)
{
OwnerName = ownerName;
Balance = initialBalance;
}

public void Deposit(decimal amount)
{
if (amount <= 0)
{
Console.WriteLine("入金額は0より大きい値を指定してください");
return;
}

Balance += amount;
}

public bool Withdraw(decimal amount)
{
if (amount <= 0 || amount > Balance)
{
return false;
}

Balance -= amount;
return true;
}

public void ShowBalance()
{
Console.WriteLine($"{OwnerName}さんの残高:{Balance}円");
}
}

使用例は次のとおりです。

C#
BankAccount account = new BankAccount("田中", 10000m);

account.Deposit(5000m);

bool succeeded = account.Withdraw(3000m);

if (succeeded)
{
Console.WriteLine("出金しました");
}
else
{
Console.WriteLine("出金できませんでした");
}

account.ShowBalance();

この例では、メソッドごとに役割を分けています。

  • Deposit:入金する

  • Withdraw:出金する

  • ShowBalance:残高を表示する

クラスが持つデータと、そのデータに対する処理をまとめることで、プログラムの構造がわかりやすくなります。

10. 初心者がつまずきやすいエラーと対処法

10-1. メソッド名のスペルミス

C#では、メソッド名の大文字と小文字が区別されます。

C#
static void ShowMessage()
{
Console.WriteLine("こんにちは");
}

次の呼び出しは、メソッド名が一致しないためエラーになります。

C#
// エラー
showMessage();

正しくは次のとおりです。

C#
ShowMessage();

エラーが出たときは、スペルだけでなく、大文字と小文字も確認しましょう。

10-2. 引数の数が合わない

メソッドが2つの引数を必要としている場合、呼び出し時にも2つの値を渡す必要があります。

C#
static int Add(int a, int b)
{
return a + b;
}

次の呼び出しは、引数が1つしかないためエラーです。

C#
// エラー
int result = Add(10);

正しくは次のように書きます。

C#
int result = Add(10, 20);

省略可能な引数が設定されている場合を除き、定義された数の引数を渡しましょう。

10-3. 引数の型が合わない

引数の型と、実際に渡す値の型が一致していない場合もエラーになります。

C#
static int DoubleValue(int number)
{
return number * 2;
}

次のコードでは、string型の値を渡しているためエラーになります。

C#
// エラー
int result = DoubleValue("10");

文字列として入力された数値を渡したい場合は、事前に変換します。

C#
string input = "10";
int number = int.Parse(input);
int result = DoubleValue(number);

入力内容が数値とは限らない場合は、int.TryParseを使うと安全です。

C#
string input = "10";

if (int.TryParse(input, out int number))
{
int result = DoubleValue(number);
Console.WriteLine(result);
}
else
{
Console.WriteLine("整数を入力してください");
}

10-4. 戻り値の型が合わない

次のメソッドは、戻り値の型としてintを指定しています。

C#
static int GetValue()
{
return 10;
}

string型の値を返すとエラーになります。

C#
static int GetValue()
{
// エラー
return "10";
}

メソッドの戻り値の型、returnする値、戻り値を受け取る変数の型を確認しましょう。

C#
int value = GetValue();

10-5. staticに関するエラー

staticメソッドからインスタンスメソッドを直接呼び出そうとすると、エラーが発生します。

C#
class Program
{
static void Main()
{
// エラー
ShowMessage();
}

void ShowMessage()
{
Console.WriteLine("こんにちは");
}
}

対処方法の一つは、インスタンスを作成することです。

C#
class Program
{
static void Main()
{
Program program = new Program();
program.ShowMessage();
}

void ShowMessage()
{
Console.WriteLine("こんにちは");
}
}

オブジェクト固有のデータを使わない処理であれば、呼び出される側もstaticにできます。

C#
static void ShowMessage()
{
Console.WriteLine("こんにちは");
}

10-6. return文を書き忘れる

戻り値があるメソッドでは、すべての実行経路で値を返す必要があります。

次のコードでは、scoreが60未満の場合に値を返さないためエラーになります。

C#
static string JudgeResult(int score)
{
if (score >= 60)
{
return "合格";
}

// scoreが60未満の場合のreturnがない
}

次のように、すべての場合に戻り値が返されるように修正します。

C#
static string JudgeResult(int score)
{
if (score >= 60)
{
return "合格";
}

return "不合格";
}

または、ifelseを使っても構いません。

C#
static string JudgeResult(int score)
{
if (score >= 60)
{
return "合格";
}
else
{
return "不合格";
}
}

11. C#のメソッドを理解するための学習ポイント

11-1. まずは小さな処理をメソッド化する

最初から複雑なメソッドを作る必要はありません。まずは、画面表示や簡単な計算など、小さな処理をメソッドにしてみましょう。

C#
static void SayHello()
{
Console.WriteLine("こんにちは");
}
C#
static int DoubleValue(int number)
{
return number * 2;
}

小さなメソッドを何度も定義して呼び出すことで、基本構文が身につきます。

11-2. 同じ処理を繰り返し書かない意識を持つ

プログラムの中で同じようなコードを何度も書いている場合は、メソッドにまとめられないか考えてみましょう。

たとえば、次のコードでは似た処理を繰り返しています。

C#
Console.WriteLine("こんにちは、田中さん");
Console.WriteLine("こんにちは、鈴木さん");
Console.WriteLine("こんにちは、佐藤さん");

メソッドにまとめると、次のように整理できます。

C#
static void Greet(string name)
{
Console.WriteLine($"こんにちは、{name}さん");
}

Greet("田中");
Greet("鈴木");
Greet("佐藤");

重複を減らすことで、修正しやすく読みやすいコードになります。

11-3. メソッド名は処理内容がわかる名前にする

メソッド名は、そのメソッドの役割を説明する重要な情報です。

たとえば、価格の合計を計算するメソッドなら、次のような名前が適しています。

C#
CalculateTotalPrice()

単にCalcDoとするよりも、具体的な名前のほうが処理内容を理解しやすくなります。

真偽値を返すメソッドでは、IsHasCanなどから始めると意図が伝わりやすくなります。

C#
IsAdult()
HasPermission()
CanWithdraw()

11-4. 引数と戻り値を図解で整理する

引数と戻り値の関係は、次のように整理できます。

呼び出し元

│ 引数を渡す

メソッドで処理する

│ 戻り値を返す

呼び出し元

足し算のメソッドなら、次のようになります。

3と5を渡す

Add(3, 5)

8を返す

コードでは次のとおりです。

C#
static int Add(int a, int b)
{
return a + b;
}

int result = Add(3, 5);

「入力が引数、出力が戻り値」と整理すると理解しやすくなります。

11-5. サンプルコードを書いて動かしてみる

メソッドは、コードを読んでいるだけでは理解しにくい部分があります。サンプルコードを実際に入力し、引数や戻り値を変更して動作を確認しましょう。

たとえば、次の点を変更してみると学習効果が高まります。

  • メソッド名を変更する

  • 引数を1つ追加する

  • 戻り値の型を変更する

  • 条件分岐を追加する

  • 同じメソッドを複数回呼び出す

  • staticを外してインスタンスから呼び出す

エラーが発生した場合も、メッセージを読み、どの部分が定義と合っていないのかを確認することが大切です。

12. C#の関数(メソッド)に関するよくある質問

12-1. C#に関数はありますか?

C#にも、一般的な意味での関数に相当する仕組みがあります。ただし、C#では基本的にクラスや構造体などの型に属するため、「メソッド」と呼ぶのが一般的です。

日常的な説明では「C#の関数」と表現されることもありますが、多くの場合はメソッドを意味します。

12-2. メソッドと関数の違いは何ですか?

一般に、オブジェクトやクラスなどの型に属する関数をメソッドと呼びます。

C#では、処理は基本的に何らかの型に属するため、メソッドという用語が使われます。一方、プログラミング全般の説明では、処理をまとめたものを広い意味で関数と呼ぶことがあります。

初心者の段階では、C#で「関数」と説明されているものは、多くの場合「メソッド」のことだと理解しておけば問題ありません。

12-3. Mainメソッドとは何ですか?

Mainメソッドは、従来形式のC#プログラムにおいて、処理を開始する入口となるメソッドです。

C#
class Program
{
static void Main()
{
Console.WriteLine("プログラム開始");
}
}

プログラムを実行すると、基本的にMainメソッドの中から処理が始まります。

現在のC#では、トップレベルステートメントを使ってMainメソッドの記述を省略することもできます。

C#
Console.WriteLine("プログラム開始");

この形式でも、コンパイラによってプログラムのエントリーポイントが生成されます。

12-4. voidとreturnの違いは何ですか?

voidは、メソッドが値を返さないことを表す戻り値の型です。

C#
static void ShowMessage()
{
Console.WriteLine("こんにちは");
}

returnは、メソッドから値を返したり、メソッドの処理を終了したりするための文です。

C#
static int Add(int a, int b)
{
return a + b;
}

voidメソッドでも、値を付けないreturn;を使って処理を途中で終了できます。

C#
static void ShowNumber(int number)
{
if (number < 0)
{
return;
}

Console.WriteLine(number);
}

12-5. メソッドはどこに書けばよいですか?

基本的には、クラスや構造体などの型の中に記述します。

C#
class Program
{
static void Main()
{
ShowMessage();
}

static void ShowMessage()
{
Console.WriteLine("こんにちは");
}
}

メソッドの中に、通常のメソッドを直接定義することはできません。ただし、ローカル関数であれば、メソッドの内部に定義できます。

C#
static void Main()
{
void ShowMessage()
{
Console.WriteLine("こんにちは");
}

ShowMessage();
}

初心者は、まずクラスの中で、Mainメソッドと同じ階層に独自のメソッドを書く方法を覚えるとよいでしょう。

12-6. 初心者はどのメソッドから覚えるべきですか?

まずは、次の4種類を順番に練習するのがおすすめです。

  1. 引数も戻り値もないメソッド

  2. 引数があり、戻り値がないメソッド

  3. 引数がなく、戻り値があるメソッド

  4. 引数と戻り値の両方があるメソッド

それぞれの例は次のとおりです。

C#
// 引数なし・戻り値なし
static void ShowMessage()
{
Console.WriteLine("こんにちは");
}

// 引数あり・戻り値なし
static void Greet(string name)
{
Console.WriteLine($"こんにちは、{name}さん");
}

// 引数なし・戻り値あり
static int GetNumber()
{
return 10;
}

// 引数あり・戻り値あり
static int Add(int a, int b)
{
return a + b;
}

この4種類を自分で定義し、呼び出せるようになれば、C#のメソッドの基本を理解できたといえます。

まとめ

C#の関数に相当する仕組みは、一般的に「メソッド」と呼ばれます。メソッドは、複数の処理をひとまとまりにし、必要な場所から再利用するための機能です。

メソッドを定義するときは、主に次の要素を指定します。

  • アクセス修飾子

  • staticの有無

  • 戻り値の型

  • メソッド名

  • 引数

  • メソッド本体

引数は呼び出し元からメソッドへ渡す値であり、戻り値はメソッドから呼び出し元へ返す結果です。

C#
static int Add(int a, int b)
{
return a + b;
}

int result = Add(10, 20);

この例では、1020が引数で、計算結果の30が戻り値です。

最初は、文字列を表示するメソッドや、2つの数値を計算するメソッドなど、小さな処理から練習しましょう。同じ処理を見つけたらメソッドにまとめる習慣を付けることで、読みやすく修正しやすいC#プログラムを書けるようになります。