C#で可変長引数のメソッドを作る方法|注意点も解説
- システム
エンジニア - C#の可変長引数のメソッドを作りたいと思っています。
- プロジェクト
マネージャー - 可変長引数のparamsをintやstringなど他の型と合わせて使用する例をみてみましょう。
C#の可変長引数とは
C#でメソッドの引数を決まった数ではなく、そのメソッドを呼び出す側で好きなだけ追加できるようにしたいことがあります。そんな時に役立つのが可変長引数のparamsです。以下がサンプルです。なおソースの先頭には「using System;」が必要です(Visual Studioであれば最初から入っています)。また、そのまま実行するためにはSystemを付与する必要があります。使用する際は、全体的にSystemを付与し使用しましょう。
public static void DispValues(params int[] ary)
{
for (int i = 0; i < ary.Length; i++) { System.Console.Write(ary[i] + " "); } System.Console.WriteLine(); // 最後に改行する } static void Main(string[] args) { DispValues(1, 2, 3); DispValues(4, 5, 6, 7, 8, 9, 10); }
可変長引数を実現するparams
上のサンプルを実行すると以下のように表示されます。
1 2 3
4 5 6 7 8 9 10
DispValuesメソッドの引数のparamsによって、好きな数の引数を指定できるのです。int型だけでなく、以下のようにstringなどの他の型も使用できます。
public static void DispStrings(params string[] ary)
{
for (int i = 0; i < ary.Length; i++)
{
Console.Write(ary[i] + ” “);
}
Console.WriteLine();
}
普通の引数と可変長引数を組み合わせて使うこともできる
以下のように普通の引数と可変長引数を組み合わせて使用することもできます。DispNamesの最初のstring keisyoは普通の引数です。
public static void DispNames(string keisyo, params string[] ary)
{
for (int i = 0; i < ary.Length; i++)
{
Console.WriteLine(ary[i] + keisyo);
}
}
static void Main(string[] args)
{
DispNames(“さん”, “太郎”, “花子”, “一郎”);
}
結果は以下になります。
太郎さん
花子さん
一郎さん
なおparamsは一番右端にしか使えません。paramsに続いて,(カンマ)で引数を追加しようとしても、エラーになります。
object型の可変長引数なら様々な型を指定できる
C#では以下のように可変長引数の型をobjectにすると、様々な型の値を引数として与えられます。このようにint型などの基本型をobject型にできるC#の機能を「ボックス化」「ボクシング」と呼びます。
public static void DispObjects(params object[] ary)
{
for (int i = 0; i < ary.Length; i++)
{
Console.Write(ary[i] + ” “);
}
Console.WriteLine();
}
static void Main(string[] args)
{
DispObjects(“太郎”, 30, ‘M’);
DispObjects(“花子”, 24, ‘F’);
}
ボックス化は手軽だが必要な時のみ使おう
上のサンプルを実行すると以下のようになります。
太郎 30 M
花子 24 F
objectによるボックス化は型を考えなくてよくなるので楽ですが、パフォーマンス(処理速度)はintなどの基本型より悪くなります。またobjectにした値を元の型に戻したい場合、元はどんな型だったかをチェックしなければなりません。
以下はobject型のparamの元の型をisでチェックして、それに応じた処理を行うサンプルです。
public static void DispTypeAndSum(params object[] ary)
{
int sum = 0;
for (int i = 0; i < ary.Length; i++)
{
if (ary[i] is string)
{
Console.WriteLine(ary[i] + ” is string”);
}
if (ary[i] is int)
{
Console.WriteLine(ary[i] + ” is int”);
sum += (int)ary[i]; // int型の時だけ合計する
}
if (ary[i] is char)
{
Console.WriteLine(ary[i] + ” is char”);
}
}
Console.WriteLine(“int value sum is ” + sum);
}
static void Main(string[] args)
{
DispTypeAndSum(“桜”, 10, ‘S’, 20);
}
結果は以下のようになります。
桜 is string
10 is int
S is char
20 is int
int value sum is 30
可変長引数がオーバーロードと競合した場合
ここまで読んできて、C#をある程度理解している人は「可変長引数がオーバーロードと競合したらどうなるのだろう?」と思ったのではないでしょうか。C#はオーバーロードという、以下のようにメソッド名が同じでも引数の数や型の違いによって、行う処理を切り替えられる機能があります。
public static void IntWork(int a)
{
Console.WriteLine(a);
}
public static void IntWork(int a, int b)
{
Console.WriteLine(a+b);
}
public static void IntWork(string s)
{
Console.WriteLine(“文字列には対応していません。”);
}
引数の数についての優先度
引数の数を複数持つことが出来るオーバーロードと可変長引数は機能として競合しています。C#ではどちらが優先されるか調べましょう。以下をご覧ください。
public static void DispVal(int a, int b)
{
Console.WriteLine(a + ” ” + b+” 2params.”);
}
public static void DispVal(params int[] ary)
{
for (int i = 0; i < ary.Length; i++)
{
Console.Write(ary[i] + ” “);
}
Console.WriteLine(ary.Length + “params.”);
}
static void Main(string[] args)
{
DispVal(1, 2);
DispVal(1, 2, 3);
}
引数の型についての優先度
上のサンプルを実行すると以下になります。
1 2 2params.
1 2 3 3params.
引数が2つの時は、可変長引数ではない方が優先されていますね。では型の違いではどうでしょうか。以下のサンプルを見てください。
public static void DispNameAndAge(System.String n, int a)
{
Console.WriteLine(n + “は” + a +”歳です。”);
}
public static void DispNameAndAge(params object[] ary)
{
for (int i = 0; i < ary.Length; i++)
{
Console.Write(ary[i] + ” “);
}
Console.WriteLine();
}
static void Main(System.String[] args)
{
DispNameAndAge(“花子”, 20);
DispNameAndAge(20, “花子”);
}
数でも型でも可変長引数の優先度は低い
上のサンプルの結果は以下になります。
花子は20歳です。
20 花子
引数がString型、int型の場合は可変引数ではない方が呼ばれ、そうでない場合は可変長引数の方が呼ばれます。可変長引数は数でも型でも優先度は低いということです。なおC#には「デフォルト引数」という機能がありますが、その場合の優先度はどうなるのでしょうか。
デフォルト引数と可変引数の優先度
以下のサンプルをご覧ください。1つ目のDispValは3つ目の引数にデフォルト値があります。
public static void DispVal(int a, int b, int c = 10)
{
Console.WriteLine(a + ” ” + b + ” ” + c + ” 第3引数はデフォルト値”);
}
public static void DispVal(params int[] ary)
{
for (int i = 0; i < ary.Length; i++) { Console.Write(ary[i] + " "); } Console.WriteLine(); } static void Main(string[] args) { DispVal(1); DispVal(1, 2); DispVal(1, 2, 3); DispVal(1, 2, 3, 4); }
可変長引数の優先度は最低
上のサンプルを実行すると、以下の結果になります。
1
1 2 10 第3引数はデフォルト値
1 2 3 第3引数はデフォルト値
1 2 3 4
引数が2つと3つの時はデフォルト引数があるDispValが呼ばれています。可変長引数の優先度が低いことが分かりますね。ちなみにデフォルト引数ありと無しでは、無しの普通のメソッドの方が優先度が高くなります。つまり優先度は以下になります。
1 デフォルト引数無し
2 デフォルト引数あり
3 可変長引数
- システム
エンジニア - 可変長数は優先度が低いので、使える場所が限られています。
- プロジェクト
マネージャー - 確かに拡張性は高くありませんが、適所に使えるようになるといいですね。
可変長引数は特に必要な場所だけで使おう
C#の可変長引数について説明してきましたがいかがでしたでしょうか。C#の可変長引数はオーバーロードにおいて優先度が低いので、拡張性が高くありません。可変長引数がどうしても必要な場所だけで使用するのが良いでしょう。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。
-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。
C#新着案件New Job
-
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(新宿駅) -
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(新宿駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円神奈川県横浜市(桜木町駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円神奈川県横浜市(桜木町駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(西新宿駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(西新宿駅)