C#の引数とは?基本の使い方から省略・参照渡し・可変長引数まで初心者向けに解説

はじめに

C#でメソッドを学び始めると、必ず出てくるのが「引数」です。引数は、メソッドに値を渡して処理内容を変えるための大切な仕組みです。

たとえば、名前を渡してあいさつ文を表示したり、数値を渡して計算したり、複数の値を受け取って結果を返したりできます。

C#の引数には、基本的な値渡しのほかに、refoutinを使った参照渡し、省略可能引数、名前付き引数、paramsを使った可変長引数など、さまざまな書き方があります。

この記事では、C#の引数について、初心者にもわかりやすいように基本から順番に解説します。

1. C#の引数とは?初心者向けに意味をわかりやすく解説

1-1. 引数はメソッドに値を渡すための仕組み

C#の引数とは、メソッドに値を渡すための仕組みです。

メソッドは、決められた処理をひとまとめにしたものです。ただし、毎回まったく同じ処理だけではなく、渡された値によって処理内容を変えたい場合があります。

たとえば、次のようなメソッドを考えてみましょう。

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

このメソッドは、nameという値を受け取り、その名前を使ってメッセージを表示します。

C#
SayHello("田中");
SayHello("佐藤");

実行結果は次のようになります。

C#
こんにちは、田中さん
こんにちは、佐藤さん

このように、メソッドに渡す値が「引数」です。

1-2. 「引数」と「パラメーター」の違い

C#では、「引数」と「パラメーター」という言葉が使われます。初心者のうちは同じように使ってしまいがちですが、厳密には意味が少し違います。

メソッドを定義するときに書く変数を「パラメーター」と呼びます。

C#
void SayHello(string name)
{
Console.WriteLine(name);
}

この場合、nameがパラメーターです。

一方、メソッドを呼び出すときに実際に渡す値を「引数」と呼びます。

C#
SayHello("田中");

この場合、"田中"が引数です。

ただし、実際の会話や学習記事では、どちらもまとめて「引数」と呼ばれることも多いです。初心者のうちは、「メソッドに渡す値や受け取る変数のこと」と理解しておけば問題ありません。

1-3. 引数を使うと何が便利になるのか

引数を使うと、同じメソッドをさまざまな値で使い回せるようになります。

たとえば、引数を使わない場合、名前ごとに別々のメソッドを作る必要があります。

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

void SayHelloSato()
{
Console.WriteLine("こんにちは、佐藤さん");
}

これでは、名前が増えるたびにメソッドも増えてしまいます。

引数を使えば、1つのメソッドで対応できます。

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

このように、引数を使うことでコードの重複を減らし、再利用しやすいプログラムを書くことができます。

1-4. C#で引数が使われる基本的な場面

C#の引数は、さまざまな場面で使われます。

たとえば、文字列を渡して表示内容を変える場合です。

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

数値を渡して計算する場合にも使います。

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

また、条件を渡して処理を分ける場合にも引数を使います。

C#
void ShowResult(bool isSuccess)
{
if (isSuccess)
{
Console.WriteLine("成功しました");
}
else
{
Console.WriteLine("失敗しました");
}
}

このように、C#の引数はメソッドを柔軟に使うための基本です。

2. C#の引数の基本的な書き方

2-1. メソッド定義で引数を指定する構文

C#で引数を受け取るメソッドを定義するには、メソッド名の後ろの丸かっこ内に、型と名前を書きます。

C#
戻り値の型 メソッド名( 引数名)
{
処理;
}

たとえば、文字列を受け取るメソッドは次のように書きます。

C#
void PrintName(string name)
{
Console.WriteLine(name);
}

string nameの部分が引数です。stringは型、nameは引数名です。

数値を受け取る場合は、次のように書きます。

C#
void PrintAge(int age)
{
Console.WriteLine($"年齢は{age}歳です");
}

このように、C#では引数ごとに型を指定する必要があります。

2-2. メソッド呼び出し時に引数を渡す方法

メソッドを呼び出すときは、丸かっこの中に渡したい値を書きます。

C#
PrintName("田中");
PrintAge(25);

PrintNameメソッドには文字列を渡し、PrintAgeメソッドには整数を渡しています。

全体のコードは次のようになります。

C#
void PrintName(string name)
{
Console.WriteLine(name);
}

PrintName("田中");

実行すると、次のように表示されます。

C#
田中

2-3. 複数の引数を渡す方法

複数の引数を使いたい場合は、カンマで区切って書きます。

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

呼び出すときも、同じ順番で値を渡します。

C#
PrintProfile("田中", 25);

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

C#
田中さんは25歳です

C#では、基本的にメソッド定義で指定した引数の順番と、呼び出し時に渡す値の順番を一致させる必要があります。

2-4. 戻り値あり・戻り値なしのメソッドと引数の関係

メソッドには、戻り値があるものとないものがあります。

戻り値がないメソッドは、voidを使います。

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

このメソッドは、引数として受け取った文字列を表示するだけで、値を返しません。

一方、戻り値があるメソッドは、戻り値の型を指定します。

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

このメソッドは、abを引数として受け取り、計算結果をint型で返します。

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

実行結果は次のようになります。

C#
8

引数はメソッドに値を渡す仕組み、戻り値はメソッドから値を返す仕組みです。

2-5. 引数の型と渡す値の型を一致させる必要がある

C#は型に厳しい言語です。そのため、引数の型と渡す値の型を一致させる必要があります。

たとえば、次のメソッドはint型の引数を受け取ります。

C#
void PrintNumber(int number)
{
Console.WriteLine(number);
}

正しい呼び出し方は次のとおりです。

C#
PrintNumber(10);

しかし、文字列を渡すとエラーになります。

C#
PrintNumber("10");

"10"は文字列であり、intではないためです。

必要な場合は、型変換を行います。

C#
int number = int.Parse("10");
PrintNumber(number);

C#の引数では、型を意識することがとても重要です。

3. 値渡しとは?C#の引数で最初に理解したい基本

3-1. C#の通常の引数は値渡し

C#の通常の引数は「値渡し」です。

値渡しとは、変数の値をコピーしてメソッドに渡す方法です。メソッド内で引数の値を変更しても、呼び出し元の変数そのものは基本的に変更されません。

C#
void ChangeNumber(int number)
{
number = 100;
}

int x = 10;
ChangeNumber(x);

Console.WriteLine(x);

実行結果は次のようになります。

C#
10

メソッド内ではnumber100に変更していますが、呼び出し元のx10のままです。

3-2. 値渡しで変数の中身がどう扱われるか

値渡しでは、メソッドに渡された値がコピーされます。

C#
int x = 10;
ChangeNumber(x);

このとき、xそのものがメソッドに渡されるのではなく、xに入っている10という値がコピーされて渡されます。

そのため、メソッド内の引数を変更しても、元の変数には影響しません。

C#
void ChangeNumber(int number)
{
number = 100;
}

このnumberは、呼び出し元のxとは別の変数のように考えると理解しやすいです。

3-3. 値型を引数に渡した場合の動き

C#の値型には、intdoubleboolcharstructなどがあります。

値型を通常の引数として渡すと、値がコピーされます。

C#
void AddTen(int number)
{
number += 10;
Console.WriteLine($"メソッド内: {number}");
}

int value = 5;
AddTen(value);

Console.WriteLine($"呼び出し元: {value}");

実行結果は次のようになります。

C#
メソッド内: 15
呼び出し元: 5

メソッド内では15になっていますが、呼び出し元のvalue5のままです。

3-4. 参照型を引数に渡した場合の注意点

C#の参照型には、string、配列、クラスなどがあります。

参照型を値渡しした場合は、「参照先を示す値」がコピーされます。そのため、オブジェクトの中身を変更すると、呼び出し元にも影響することがあります。

C#
void ChangeArray(int[] numbers)
{
numbers[0] = 100;
}

int[] values = { 1, 2, 3 };
ChangeArray(values);

Console.WriteLine(values[0]);

実行結果は次のようになります。

C#
100

配列そのものの参照先は同じなので、メソッド内で配列の中身を変更すると、呼び出し元にも反映されます。

ただし、メソッド内で引数に新しい配列を代入しても、呼び出し元の変数が別の配列を指すようになるわけではありません。

C#
void ReplaceArray(int[] numbers)
{
numbers = new int[] { 100, 200, 300 };
}

int[] values = { 1, 2, 3 };
ReplaceArray(values);

Console.WriteLine(values[0]);

実行結果は次のようになります。

C#
1

参照型でも、通常の引数は値渡しである点に注意しましょう。

3-5. 値渡しでよくある勘違い

値渡しでよくある勘違いは、「メソッド内で引数を変更したら、呼び出し元の変数も変わる」と思ってしまうことです。

値型の場合、通常は変わりません。

C#
void Change(int x)
{
x = 999;
}

int number = 1;
Change(number);

Console.WriteLine(number);

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

C#
1

一方、参照型の場合は、オブジェクトの中身を変更すると呼び出し元にも影響します。

C#
void ChangeName(Person person)
{
person.Name = "佐藤";
}

このように、C#の引数を理解するには、「値型か参照型か」と「変数そのものを変更しているのか、オブジェクトの中身を変更しているのか」を分けて考えることが大切です。

4. 参照渡しとは?ref・out・inの違いを解説

4-1. 参照渡しとは何か

参照渡しとは、変数そのものをメソッドに渡し、メソッド内で呼び出し元の変数を変更できるようにする方法です。

C#では、refoutinというキーワードを使って参照渡しを行います。

通常の値渡しでは、メソッド内で引数に別の値を代入しても、呼び出し元の変数は変わりません。

しかし、refoutを使うと、メソッド内で変更した内容を呼び出し元に反映できます。

4-2. refを使って引数の値を変更する方法

refを使うと、メソッド内で引数の値を変更し、その変更を呼び出し元に反映できます。

C#
void ChangeNumber(ref int number)
{
number = 100;
}

int x = 10;
ChangeNumber(ref x);

Console.WriteLine(x);

実行結果は次のようになります。

C#
100

refを使う場合は、メソッド定義側と呼び出し側の両方にrefを書く必要があります。

また、refで渡す変数は、呼び出し前に値が代入されている必要があります。

C#
int x = 10;
ChangeNumber(ref x);

初期化されていない変数をrefで渡すことはできません。

4-3. outを使ってメソッドから複数の値を返す方法

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

通常、メソッドの戻り値は1つですが、outを使うと複数の値を返すような書き方ができます。

C#
void GetUserInfo(out string name, out int age)
{
name = "田中";
age = 25;
}

GetUserInfo(out string userName, out int userAge);

Console.WriteLine(userName);
Console.WriteLine(userAge);

実行結果は次のようになります。

C#
田中
25

outを使う場合、メソッド内で必ず値を代入する必要があります。

また、呼び出し前に変数を初期化していなくても使えます。

C#
int result;

のように事前に宣言してもよいですし、次のように呼び出し時に宣言することもできます。

C#
GetUserInfo(out string name, out int age);

よく使われる例として、int.TryParseがあります。

C#
bool success = int.TryParse("123", out int number);

if (success)
{
Console.WriteLine(number);
}

文字列を数値に変換できた場合、numberに変換結果が入ります。

4-4. inを使って読み取り専用で引数を渡す方法

inは、参照渡しをしながら、メソッド内で値を変更できないようにするためのキーワードです。

C#
void PrintNumber(in int number)
{
Console.WriteLine(number);
}

inで渡された引数は、メソッド内で読み取り専用として扱われます。

C#
void PrintNumber(in int number)
{
// number = 100; // エラー
Console.WriteLine(number);
}

大きな構造体をコピーせずに渡したいが、メソッド内では変更されたくない場合に使われます。

初心者のうちは、inは「変更しない参照渡し」と理解しておくとよいでしょう。

4-5. ref・out・inの使い分け

refoutinは、それぞれ目的が異なります。

refは、呼び出し元の変数をメソッド内で変更したいときに使います。

C#
void AddOne(ref int number)
{
number++;
}

outは、メソッドから値を返したいときに使います。

C#
bool TryGetValue(out int value)
{
value = 10;
return true;
}

inは、値を変更せずに参照として渡したいときに使います。

C#
void ShowValue(in int value)
{
Console.WriteLine(value);
}

基本的には、通常の引数で十分な場合が多いです。必要な場面でだけ、refoutinを使いましょう。

4-6. 参照渡しを使うときの注意点

参照渡しは便利ですが、使いすぎるとコードがわかりにくくなります。

たとえば、refを使うと、メソッドを呼び出しただけで変数の値が変わる可能性があります。

C#
UpdateValue(ref x);

このようなコードは、メソッドの中身を見ないと何が起きるかわかりにくくなります。

また、outを多用すると、メソッドが複数の責任を持ちすぎることがあります。複数の値を返したい場合は、クラス、構造体、タプルを使う方法もあります。

参照渡しは、必要なときだけ使うのが基本です。

5. 引数を省略する方法:省略可能引数と名前付き引数

5-1. 省略可能引数とは

省略可能引数とは、メソッド呼び出し時に省略できる引数のことです。

通常、メソッドに引数がある場合は、呼び出し時に必ず値を渡す必要があります。

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

PrintMessage("こんにちは");

しかし、省略可能引数を使うと、引数を渡さなかった場合に使うデフォルト値を設定できます。

C#
void PrintMessage(string message = "こんにちは")
{
Console.WriteLine(message);
}

この場合、引数を省略して呼び出せます。

C#
PrintMessage();

実行結果は次のようになります。

C#
こんにちは

5-2. デフォルト値を設定して引数を省略する方法

省略可能引数を使うには、引数にデフォルト値を設定します。

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

このメソッドは、ageを省略できます。

C#
ShowProfile("田中");
ShowProfile("佐藤", 30);

実行結果は次のようになります。

C#
田中さんは20歳です
佐藤さんは30歳です

省略された場合は、デフォルト値の20が使われます。

5-3. 名前付き引数とは

名前付き引数とは、引数名を指定して値を渡す方法です。

通常、C#では引数の順番に従って値を渡します。

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

ShowProfile("田中", 25);

名前付き引数を使うと、次のように書けます。

C#
ShowProfile(name: "田中", age: 25);

引数名が明確になるため、コードの意味がわかりやすくなります。

5-4. 名前付き引数で読みやすくメソッドを呼び出す方法

名前付き引数は、引数が複数ある場合に特に便利です。

C#
void CreateUser(string name, int age, bool isAdmin)
{
Console.WriteLine($"{name}, {age}, 管理者: {isAdmin}");
}

通常の呼び出しでは、値だけを見ると意味がわかりにくいことがあります。

C#
CreateUser("田中", 25, true);

名前付き引数を使うと、何を渡しているのかが明確になります。

C#
CreateUser(name: "田中", age: 25, isAdmin: true);

特に、truefalseのような真偽値を渡す場合は、名前付き引数を使うと読みやすくなります。

C#
CreateUser(name: "田中", age: 25, isAdmin: true);

5-5. 省略可能引数と名前付き引数を組み合わせる方法

省略可能引数と名前付き引数は組み合わせて使えます。

C#
void SendMail(string to, string subject = "件名なし", string body = "本文なし")
{
Console.WriteLine($"宛先: {to}");
Console.WriteLine($"件名: {subject}");
Console.WriteLine($"本文: {body}");
}

たとえば、subjectは省略して、bodyだけ指定したい場合があります。

名前付き引数を使えば、次のように書けます。

C#
SendMail("test@example.com", body: "こんにちは");

この場合、subjectにはデフォルト値の"件名なし"が使われ、bodyには"こんにちは"が渡されます。

5-6. 省略可能引数を使うときの注意点

省略可能引数を使うときは、必須の引数を先に書き、省略可能な引数を後ろに書く必要があります。

正しい例です。

C#
void ShowProfile(string name, int age = 20)
{
}

次のように、省略可能引数の後ろに必須引数を書くとエラーになります。

C#
// エラー
void ShowProfile(int age = 20, string name)
{
}

また、省略可能引数を増やしすぎると、メソッドの使い方が複雑になることがあります。引数が多くなりすぎる場合は、クラスにまとめることも検討しましょう。

6. 可変長引数とは?paramsを使って複数の値を受け取る方法

6-1. 可変長引数とは

可変長引数とは、渡す引数の数を自由に変えられる引数のことです。

たとえば、数値をいくつでも渡して合計したい場合があります。

C#
Sum(1, 2);
Sum(1, 2, 3);
Sum(1, 2, 3, 4, 5);

このような書き方を可能にするのが、paramsキーワードです。

6-2. paramsキーワードの基本構文

paramsを使うと、複数の値をまとめて受け取れます。

C#
void メソッド名(params [] 引数名)
{
処理;
}

たとえば、複数の整数を受け取るメソッドは次のように書きます。

C#
void PrintNumbers(params int[] numbers)
{
foreach (int number in numbers)
{
Console.WriteLine(number);
}
}

呼び出し時は、配列を明示しなくても複数の値を渡せます。

C#
PrintNumbers(1, 2, 3);

6-3. 配列として引数を受け取る仕組み

paramsで受け取った値は、メソッド内では配列として扱われます。

C#
void PrintNumbers(params int[] numbers)
{
Console.WriteLine(numbers.Length);
}

次のように呼び出すと、numbersには3つの要素が入ります。

C#
PrintNumbers(10, 20, 30);

実行結果は次のようになります。

C#
3

また、配列をそのまま渡すこともできます。

C#
int[] values = { 1, 2, 3 };
PrintNumbers(values);

paramsは、呼び出し側の書き方を簡単にするための仕組みです。

6-4. paramsを使った実用的なサンプルコード

複数の数値を受け取り、合計値を返すメソッドを作ってみましょう。

C#
int Sum(params int[] numbers)
{
int total = 0;

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

return total;
}

呼び出し例です。

C#
int result1 = Sum(1, 2);
int result2 = Sum(1, 2, 3, 4, 5);

Console.WriteLine(result1);
Console.WriteLine(result2);

実行結果は次のようになります。

C#
3
15

引数の数が変わっても、同じメソッドで処理できます。

6-5. paramsを使うときのルールと注意点

paramsを使うときには、いくつかのルールがあります。

まず、params引数は基本的に引数リストの最後に書きます。

C#
void Print(string title, params int[] numbers)
{
}

次のように、paramsの後ろに通常の引数を書くことはできません。

C#
// エラー
void Print(params int[] numbers, string title)
{
}

また、1つのメソッドで使えるparamsは1つだけです。

C#
// エラー
void Print(params int[] numbers, params string[] names)
{
}

さらに、paramsは便利ですが、何でも詰め込みすぎるとメソッドの意図がわかりにくくなります。渡す値の意味が明確な場合に使いましょう。

7. 引数に関するよくあるエラーと対処法

7-1. 引数の数が一致しないエラー

C#では、メソッド定義で指定した引数の数と、呼び出し時に渡す引数の数が一致していないとエラーになります。

C#
void ShowName(string name)
{
Console.WriteLine(name);
}

ShowName();

このコードは、nameに渡す値がないためエラーになります。

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

C#
ShowName("田中");

複数の引数がある場合も同じです。

C#
void ShowProfile(string name, int age)
{
Console.WriteLine($"{name} {age}");
}

このメソッドを呼び出すには、2つの引数が必要です。

C#
ShowProfile("田中", 25);

7-2. 引数の型が一致しないエラー

引数の型が一致しない場合もエラーになります。

C#
void PrintAge(int age)
{
Console.WriteLine(age);
}

PrintAge("25");

PrintAgeint型を受け取るため、文字列の"25"は渡せません。

数値として渡すなら、次のように書きます。

C#
PrintAge(25);

文字列を数値に変換する場合は、int.Parseint.TryParseを使います。

C#
if (int.TryParse("25", out int age))
{
PrintAge(age);
}

7-3. refやoutを付け忘れたときのエラー

refoutを使うメソッドでは、定義側だけでなく呼び出し側にもキーワードを書く必要があります。

C#
void Change(ref int number)
{
number = 100;
}

int x = 10;
Change(x);

このコードはエラーになります。呼び出し側にもrefが必要です。

C#
Change(ref x);

outも同じです。

C#
void GetValue(out int number)
{
number = 100;
}

GetValue(out int x);

refoutは、メソッドが呼び出し元の変数に影響することを明示するため、呼び出し側にも書く必要があります。

7-4. 省略可能引数の順番に関するエラー

省略可能引数は、必須引数より後ろに書く必要があります。

C#
void Show(string name, int age = 20)
{
}

これは正しい書き方です。

一方、次のように省略可能引数の後に必須引数を書くとエラーになります。

C#
// エラー
void Show(int age = 20, string name)
{
}

なぜなら、呼び出し時にどの引数を省略したのか判断しづらくなるためです。

対処法は、必須引数を前に、省略可能引数を後ろに並べることです。

C#
void Show(string name, int age = 20)
{
}

7-5. paramsと通常の引数を組み合わせるときのエラー

paramsを通常の引数と組み合わせる場合は、paramsを最後に書きます。

C#
void PrintNumbers(string title, params int[] numbers)
{
}

このメソッドは正しく呼び出せます。

C#
PrintNumbers("点数", 80, 90, 100);

しかし、次のようにparamsの後に引数を書くとエラーになります。

C#
// エラー
void PrintNumbers(params int[] numbers, string title)
{
}

paramsは複数の値をまとめて受け取るため、最後に置かないと、どこまでが可変長引数なのか判断できません。

8. C#の引数を使いこなすための実践例

8-1. 文字列を引数に渡すサンプル

文字列を引数に渡す基本的なサンプルです。

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

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

実行結果です。

C#
こんにちは、田中さん
こんにちは、佐藤さん

引数を変えるだけで、同じメソッドを別の名前に対して使えます。

8-2. 数値を引数に渡して計算するサンプル

数値を引数に渡して、計算結果を返すサンプルです。

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

int result = Multiply(4, 5);

Console.WriteLine(result);

実行結果です。

C#
20

このように、引数で数値を受け取り、戻り値で計算結果を返す書き方はよく使われます。

8-3. 複数の引数で処理を分けるサンプル

複数の引数を使うと、条件に応じて処理を変えることもできます。

C#
void ShowPrice(string itemName, int price, bool includeTax)
{
if (includeTax)
{
int taxIncludedPrice = (int)(price * 1.1);
Console.WriteLine($"{itemName}: {taxIncludedPrice}円(税込)");
}
else
{
Console.WriteLine($"{itemName}: {price}円(税抜)");
}
}

ShowPrice("ノート", 100, true);
ShowPrice("ペン", 80, false);

実行結果です。

C#
ノート: 110円(税込)
ペン: 80円(税抜)

引数によって、表示内容や処理内容を柔軟に変えられます。

8-4. refを使って値を変更するサンプル

refを使うと、メソッド内で変更した値を呼び出し元に反映できます。

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

int value = 10;
DoubleValue(ref value);

Console.WriteLine(value);

実行結果です。

C#
20

DoubleValueメソッド内でnumberを2倍にした結果が、呼び出し元のvalueにも反映されています。

8-5. outを使って処理結果を返すサンプル

outを使うと、メソッドから追加の値を返せます。

C#
bool Divide(int a, int b, out int result)
{
if (b == 0)
{
result = 0;
return false;
}

result = a / b;
return true;
}

呼び出し例です。

C#
if (Divide(10, 2, out int answer))
{
Console.WriteLine($"結果: {answer}");
}
else
{
Console.WriteLine("割り算できません");
}

実行結果です。

C#
結果: 5

この例では、割り算に成功したかどうかを戻り値で返し、計算結果をout引数で返しています。

8-6. paramsを使って合計値を求めるサンプル

paramsを使うと、任意の数の引数を受け取れます。

C#
int Sum(params int[] numbers)
{
int total = 0;

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

return total;
}

Console.WriteLine(Sum(1, 2, 3));
Console.WriteLine(Sum(10, 20, 30, 40));

実行結果です。

C#
6
100

引数の数が違っても、同じSumメソッドで合計できます。

9. C#の引数に関するよくある質問

9-1. 引数と戻り値の違いは何ですか?

引数は、メソッドに渡す値です。戻り値は、メソッドから返ってくる値です。

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

この例では、abが引数で、return a + b;で返される値が戻り値です。

引数は「メソッドに入れる値」、戻り値は「メソッドから出てくる値」と考えるとわかりやすいです。

9-2. 引数なしのメソッドは作れますか?

はい、作れます。

引数が不要な場合は、丸かっこの中を空にします。

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

SayHello();

引数なしのメソッドは、毎回同じ処理を実行したい場合に使います。

9-3. 引数はいくつまで指定できますか?

C#では、複数の引数を指定できます。

C#
void Show(string name, int age, string address)
{
}

ただし、引数が多すぎるメソッドは読みにくくなります。

目安として、引数が多くなってきたら、関連する値をクラスや構造体にまとめることを検討しましょう。

C#
class User
{
public string Name { get; set; }
public int Age { get; set; }
}

引数の数を減らすことで、メソッドの意味がわかりやすくなります。

9-4. 参照渡しはいつ使うべきですか?

参照渡しは、呼び出し元の変数をメソッド内で変更したい場合に使います。

たとえば、値を入れ替える処理ではrefが使えます。

C#
void Swap(ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}

また、処理結果を追加で返したい場合にはoutが使われます。

C#
bool success = int.TryParse("123", out int number);

ただし、参照渡しを多用するとコードがわかりにくくなるため、通常の引数や戻り値で表現できる場合はそちらを優先しましょう。

9-5. 省略可能引数とメソッドのオーバーロードはどちらを使うべきですか?

省略可能引数は、デフォルト値を使って簡単に呼び出したい場合に便利です。

C#
void ShowMessage(string message = "こんにちは")
{
}

一方、メソッドのオーバーロードは、引数の型や数によって処理を変えたい場合に便利です。

C#
void Print(int number)
{
Console.WriteLine(number);
}

void Print(string text)
{
Console.WriteLine(text);
}

単純にデフォルト値を設定したいだけなら省略可能引数、引数の種類によって処理内容を変えたいならオーバーロードを使うとよいでしょう。

9-6. paramsと配列引数の違いは何ですか?

配列引数は、呼び出し時に配列を渡します。

C#
void PrintNumbers(int[] numbers)
{
}

int[] values = { 1, 2, 3 };
PrintNumbers(values);

一方、paramsを使うと、配列を作らずに複数の値を直接渡せます。

C#
void PrintNumbers(params int[] numbers)
{
}

PrintNumbers(1, 2, 3);

メソッド内では、どちらも配列として扱えます。

つまり、paramsは呼び出し側の書き方を簡単にするための仕組みです。

まとめ

C#の引数は、メソッドに値を渡して処理を柔軟にするための重要な仕組みです。

基本的な引数では、メソッド定義時に型と名前を指定し、呼び出し時に値を渡します。複数の引数を渡す場合はカンマで区切り、引数の型と渡す値の型を一致させる必要があります。

C#の通常の引数は値渡しです。値型では値がコピーされ、メソッド内で変更しても呼び出し元には影響しません。参照型の場合は、参照先のオブジェクトの中身を変更すると呼び出し元にも影響することがあります。

呼び出し元の変数を変更したい場合はref、メソッドから値を返したい場合はout、読み取り専用で参照渡ししたい場合はinを使います。ただし、参照渡しはコードが複雑になりやすいため、必要な場面でだけ使うことが大切です。

また、省略可能引数を使えば引数を省略でき、名前付き引数を使えば呼び出し時の意味をわかりやすくできます。paramsを使えば、数が決まっていない複数の値をまとめて受け取れます。

C#の引数を理解すると、メソッドをより柔軟に使えるようになり、読みやすく再利用しやすいコードを書けるようになります。まずは基本の値渡しから理解し、必要に応じてrefoutin、省略可能引数、名前付き引数、paramsを使い分けていきましょう。