C# 4.0の新機能(2) Named and optional parameters

今回参考にしたのはMSDNと、前回と同様未確認飛行さんのところです。特に未確認飛行さんのところは、もうパーフェクトすぎてリンクだけでいいんじゃないかと思ったのですが、せっかく(?)なのでコードを書いてみます。


MSDN 名前付き引数と省略可能な引数 (C# プログラミング ガイド)
オプション引数・名前付き引数


説明はソースの中のコメントに書きました。

class Program
{
  static void Main(string[] args)
  {
    CallCalculateBMI();
    CallCalculateBMIDefault();
  }

  private static void CallCalculateBMI()
  {
    //   (01)今まで通り
    Console.WriteLine("(01) " + CalculateBMI(60, 170));

    //   (02)引数名を指定
    Console.WriteLine("(02) " + CalculateBMI(weight: 60, height: 170));

    //   (03)引数名を指定すれば順不同
    Console.WriteLine("(03) " + CalculateBMI(height: 170, weight: 60));

    //   (04)引数名がついていないと順番で見るので先頭ならなしでも可
    Console.WriteLine("(04) " + CalculateBMI(60, height: 170));

    //   (05)先頭に引数名をつけて、後方についていないのは判断できないので不可
    //  Console.WriteLine(CalculateBMI(height: 170, 60 ));


    Console.WriteLine("--------");
  }

  private static void CallCalculateBMIDefault()
  {
    //   (06)-1 Default値と同じ数値を今まで通り指定
    Console.WriteLine("(06)-1 " + CalculateBMIDefault(70, 180));
    
    //   (06)-2 Default値があるので引数を指定しないで指定
    Console.WriteLine("(06)-2 " + CalculateBMIDefault());


    //   (07)-1 1つだけ引数を指定。先頭に適用され、後方はDefault値が使われる
    Console.WriteLine("(07)-1 " + CalculateBMIDefault(80));

    //   (07)-2 両方に指定したのと同じ結果になる
    Console.WriteLine("(07)-2 " + CalculateBMIDefault(80,180));


    //   (08)-1 Defalut値なしと同様、引数名指定ができる
    Console.WriteLine("(08)-1 " + CalculateBMIDefault(weight: 60, height: 170));

    //   (08)-2 Defalut値なしと同様、引数名を指定すれば順不同
    Console.WriteLine("(08)-2 " + CalculateBMIDefault(height: 170, weight: 60));


    //   (09)-1 順不同で1つだけ指定も可能(weight指定)
    Console.WriteLine("(09)-1 " + CalculateBMIDefault(weight: 60));

    //   (09)-2 (09)-1と同じ
    Console.WriteLine("(09)-2 " + CalculateBMIDefault(weight: 60, height: 180));


    //   (10)-1 順不同で1つだけ指定も可能(height指定)
    Console.WriteLine("(10)-1 " + CalculateBMIDefault(height: 160));

    //   (10)-2 (10)-1と同じ
    Console.WriteLine("(10)-2 " + CalculateBMIDefault(weight: 70, height: 160));


    Console.ReadLine();
  }

  ///


  /// BMIを計算
  ///

  ///
  /// BMI計算式 体重(kg) / (身長(m) * 身長(m)) を小数点第2位で丸める
  ///
  /// 体重(kg)
  /// 身長(cm)
  /// BMI
  static double CalculateBMI(double weight, double height)
  {
    double cm = height / 100;
    return Math.Round(weight / (cm * cm), 2 );
  }

  ///


  /// BMIを計算。Optionalで値をセット済み。
  ///

  static double CalculateBMIDefault(double weight = 70, double height = 180)
  {
    double cm = height / 100;
    return Math.Round(weight / (cm * cm) , 2 );
  }
}

結果はこんな感じ


今まで、オーバーロードで行っていたことがこれで行えます。なんだかとってもスッキリしていていい感じ!Namedにすると明確になるから間違いも少なくなりそうだし。
ただし、呼ばれる側を変更した場合、呼ぶ側がコンパイルしないと反映がされません。これはとても大事なことですね。基本的に公開するようなものは仕様がきっちりしているはずですが(建前上)、それを考えると適材適所でしょうか。あとはCOMの使用。特にExcelを使う時などは、いらん引数をいっぱいつけて呼ばねばならなかったところが大変すっきり呼べるのがありがたいです。こういうところにはジャンジャン使っていくことにします!