メソッド -変化する引数の数-

ホームC#プログラミング応用講義 > 変化する引数の数

目次

引数の数

オーバーロードは既習事項です。オーバーロードでは、引数の数の違いがメソッド判別の鍵になる要素の一つです。

ここで述べるのはオーバーロードとは性質が異なります。
ここでは「同じメソッドで同じ型の引数を、引数の数は不明のまま受け取る」ということです。

引数が違っても値を受けることができれば便利です。配列を渡すのでもなく、引数の数を実行時に自由に選択できます。

例えば、ドラマには大まかに2つの情報があります。
それは「ドラマ名」と「主演」です。その2つの情報を表示する機能を実装したいとします。

しかし、この2つは必ずしもいつも両方わかっているとは限りません。
例えば、ドラマ名はわかっているのに主演はわからないということもありますし、その逆もあります。

そのような場合、オーバーロードを利用することによって解決できます。そして、オーバーロードを使って解決するのが一般的です。
ところが柔軟性の高い C# では、1つのメソッドを使ってその機能を実装することができます。

それは、引数の数が違っても扱える機能があるからです。ここでは、型は同じでなければなりません。
引数に配列を渡すことはできますが、それにさらに機能を付け加えるのです。

このような機能を実装するには、仮引数に、すなわちメソッド定義部の引数に以下のように定義します。
... (params 型[ ] 配列名)
パラメータとは引数のことですが、それの省略形の複数形といったところでしょうか。params というのは。
それはともかく、ここでは渡される情報は string で、配列名を「cast」とします。

コーディング

コーディングといっても、コーディングするのは私で、皆さんはサンプルを理解するだけです。
その代わり、しっかり理解してください。

using System;

class TRICK
{
    public static void Main(string[] args)
    {
        TRICK tri = new TRICK();
        
        tri.Show("トリック");
        tri.Show("トリック","仲間由紀恵");
        tri.Show("トリック","山田奈緒子","仲間由紀恵");
    }
    
    private void Show(params string[] cast)
    {
        int length = cast.Length;
        
        Console.WriteLine("渡された引数:");
        for (int i=0;i<length;i++)
            Console.WriteLine(cast[i]);
        
        if (length == 1)
        {
            Console.WriteLine("\n" + "ドラマ名: " + cast[0] + "\n");
        }
        else if (length == 2)
        {
            Console.WriteLine("\n" + "ドラマ名: " + cast[0]);
            Console.WriteLine("主演 : " + cast[1] + "\n");
        }
    }
}
注目すべきなのは以下の部分です。
private void Show(params string[] cast)
この仮引数の部分を見ると、先ほど述べた構文と同じです。
よって、この Show() メソッドは string 型の引数を、その数に関係なく受け取ることができます

とはいえ、欲しい情報は 2 つです。前にも言ったように「ドラマ名」と「主演」です。
ここでは、「ドラマ名」が必ず先にわかることが前提となっていますが、その引数に関わらず受け取っていることは確認できます。

渡される実引数は、ここでは string 配列を利用して渡されることになります。よって、直接 string 配列を渡しても問題なく利用できます。

まとめ

params は簡単な機能です。そして一見、オーバーロードを利用するものと似ています。

ところが実際には params を利用することはかなり少ない、またはないと言っていいかもしれません。
params を利用するよりもオーバーロードで複数のメソッドを定義したほうが、逆にパフォーマンスがよくなる場合がほとんどです。

いくつもオーバーロードするより1つのメソッドで済ませたほうがいいと思うかもしれませんが、多くの場合 params をオーバーロードの代わりに使うことはできません。
上のサンプルをオーバーロードで実装するなら、以下のようになるでしょう。
using System;

class TRICK
{
    public static void Main(string[] args)
    {
        TRICK tri = new TRICK();
        
        tri.Show("トリック");
        tri.Show("トリック","仲間由紀恵");
        tri.Show("トリック","山田奈緒子","仲間由紀恵");
    }
    
    private void Show(string title)
    {
        Console.WriteLine("ドラマ名: " + title);
    }
    
    private void Show(string title,string cast)
    {
        Console.WriteLine("ドラマ名: " + title);
        Console.WriteLine("主演:" + cast);
    }
    
    private void Show(string title,string act_name,string cast)
    {
        Console.WriteLine("ドラマ名: " + title);
        Console.WriteLine("役名:" + act_name);
        Console.WriteLine("主演:" + cast);
    }
}
それぞれの Show() メソッドは大変簡潔な仕様になっています。
このように多くの場合、params を無視して、オーバーロードで実装したほうがいいでしょう。

じゃあ、なぜ説明するのか。
プログラミングは必要なものを完璧にすれば完璧になるというわけではありません。
params が余分かどうかは各々のプログラマの考え方によって違いますが、いろいろ拾っていくことが結果的に習得の近道になります。

[ ステップアップC# ] [ C#プログラミング応用講義 ]