講義メモ

・p.192「refとout:outキーワード」の補足後、p.195「メソッドのオーバーロード」に進みます

p.192 refとout:outキーワード

・refキーワードの上位版がoutキーワードで、refの「実引数はなんらかの値が代入されている必要がある」という制限がない
※C#のバージョン7以降では、outキーワードの仕様が強化され、outキーワードで指定する実引数は、
 事前の定義が不要になり「out 型 実引数名」とすれば良い。
 この実引数は呼出し以降にそのまま利用可能。

参考:配列を渡して最大値と最小値を返すメソッド

using System;
class MyClass
{
    public void ArrayMaxMin(double[] x, out double max, out double min) { //max,minは参照渡し
        max = Double.MinValue; min = Double.MaxValue; //仮に最小値・最大値にしておく
        foreach (var w in x) { //全要素について繰返す
            max = (max > w) ? max : w; //最大値を更新
            min = (min < w) ? min : w; //最小値を更新
        }
    }
}
class outkeyword01
{
    public static void Main()
    {
        double[] a = {125.3, 16.25, 52.8}; 
        MyClass mc = new MyClass();
        mc.ArrayMaxMin(a, out double maxv, out double minv);
        Console.WriteLine("max = {0}, min = {1}", maxv, minv);
    }
}

提出フォロー:アレンジ演習:p.194 outkeyword01.cs

・変数cの定義を省き、実引数の指定を「out double c」とできることを確認しよう

作成例

//アレンジ演習:p.194 outkeyword01.cs
using System;
class MyClass
{
    public void Square(double x, double y, out double s) { //仮引数sは参照渡し
        s = x * y;
    }
}
class outkeyword01
{
    public static void Main()
    {
        //double a = 125.3, b = 16.25, c;
        double a = 125.3, b = 16.25; //変数cを削除
        MyClass mc = new MyClass();
        //cには値を代入していません ⇒ 宣言すらしていません
        mc.Square(a, b, out double c); //out指定の実引数は事前の宣言が不要
        Console.WriteLine("縦{0}m, 横{1}mの長方形の面積は{2}平方メートル", a, b, c);
    }
}

p.195 メソッドのオーバーロード

・p.168のとおり、シグニチャ(引数の数、型、並び)が異なるコンストラクタを複数定義できることをオーバーロードという
・メソッドもオーバーロードが可能で、シグニチャが異なる同じ名前のメソッドを複数定義できる
・なお、メソッドのシグニチャには戻り値型は含まれないので、戻り値型のみが異なるメソッドの複数定義はできない
・これは呼び出し時に区別できないから
・なお、整数⇒実数のように暗黙の型変換により一致するオーバーロードがあれば、それが採用される
・メソッドのオーバーロードにより、同じ意味のメソッドは同じ名前にできる

アレンジ演習:p.195 overload01.cs

・第5のバージョンとして「Method(double x, double y)」を適当な内容で追加し、呼び出せることを確認しよう
・Mainメソッドで、m.Method(5.1, 6)を呼び出すと、暗黙の型変換によりこの第5のバージョンが動作することを確認しよう

作成例

//アレンジ演習:p.195 overload01.cs
using System;
class manymethods {
    public int Method(int x) {
        Console.WriteLine("第1のバージョンが呼ばれました");
        return x + 10;
    }
    public double Method(double x) {
        Console.WriteLine("第2のバージョンが呼ばれました");
        return x * 2;
    }
    public string Method(string x) {
        Console.WriteLine("第3のバージョンが呼ばれました");
        return x += "です";
    }
    public int Method(int x, int y) {
        Console.WriteLine("第4のバージョンか呼ばれました");
        return x + y;
    }
    public double Method(double x, double y) { //【以下追加】
        Console.WriteLine("第5のバージョンか呼ばれました");
        return x + y;
    }
}
class overload01 {
    public static void Main() {
        manymethods m = new manymethods();
        Console.WriteLine("その戻り値は「{0}」です", m.Method(3)); //intなので①
        Console.WriteLine("その戻り値は「{0}」です", m.Method(3.2)); //doubleなので②
        Console.WriteLine("その戻り値は「{0}」です", m.Method("粂井")); //stringなので③
        Console.WriteLine("その戻り値は「{0}」です", m.Method(5, 6)); //int,intなので④
        Console.WriteLine("その戻り値は「{0}」です", m.Method(5.1, 6)); //【追加】double,intだが⑤
    }
}

p.197 Mainメソッドのオーバーロード

・Mainメソッドは特殊なメソッドであり、コンソールプログラム等の動作の始点になる
・通常、public static voidとし、引数は指定しないが、バリエーション(オーバーロード)がある。
・戻り値型をvoidからintにすると「return 整数値」が記述可能になり、このプログラムを呼び出した元に整数値を返すことができる
・なお、VisualStudioのデバッグ機能から呼び出した場合は、返される値は表示されないが、一般に、正常終了したら0を、
 でなければ0以外を返すことが多い
・Windowsではビルド済のプログラムをVisualStudioを介さずに実行し、戻り値を表示する方法がある(後述)
・また、引数にstring[]=文字列配列を指定すると、起動時に、システムから複数の文字列を渡すことができる
・この文字列をコマンドライン引数という
・VisualStudioでは、デバッグのプロパティでコマンドライン引数を指定できる
・Windowsではビルド済のプログラムをVisualStudioを介さずに実行し、実行時にコマンドライン引数を指定する方法がある(後述)

p.198 main01.cs:VisualStudioにおける実行方法

① ソースを記述する
②「デバッグ」「●のデバッグプロパティ」
③「コマンドライン引数」に「cat dog apple」と入力
④「ファイル」「すべて保存」
⑤「デバッグなしで開始」

アレンジ演習:p.198 main01.cs

・変数nの宣言と代入を初期化にまとめよう
・forは前判定繰返しなので、nが0の場合、繰返し内容は1度も実行されない。よって、if文は不要なことを確認しよう

作成例

//アレンジ演習:p.198 main01.cs
using System;
class main01 {
    public static int Main(string[] s) { //コマンドライン引数を受け取り、整数値を返すMain
        int n = s.Length; //【変更】コマンドライン引数の数を得る
        Console.WriteLine("引数の個数は{0}個です", n);
        for (int i = 0; i < n; i++) { //全要素について繰返す
            Console.WriteLine("引数{0} : {1}", i + 1, s[i]);
        }
        return 0;
    }
}

p.198 main01.cs:開発者用コマンドプロンプトにおける実行方法

① ソースを記述し「ビルド」「ソリューションのビルド」(※既に実行済なら不用)
②「ツール」「コマンドライン」「開発者用コマンドプロンプト」
③ エクスプローラで「プロジェクト名.exe」ファイルがあるフォルダを探す
 例:\ha251_AkibaC#\chap8\chap8\bin\Debug\chap8.exe
④「プロジェクト名.exe」ファイルをエクスプローラから開発者用コマンドプロンプトへドラッグ&ドロップ
⑤ パス名を含むファイル名がペーストされるので、空白を挟みつつ、コマンドライン引数を入力
 例:D:\ha251_AkibaC#\chap8>D:\ha251_AkibaC#\chap8\chap8\bin\Debug\chap8.exe boo hoo woo
⑥ Enterキーで実行
⑦ 実行後「echo %errorlevel%」と入力すると、returnされた値が表示される

アレンジ演習:p.198 main02.cs

・returnを実行すると後続の処理は行われないので、elseブロックが不要なことを確認しよう
・実行しても何も表示されないので、確認用に各returnの前で返した値を表示しよう
・わかりづらく実行環境に依存するバッチファイルを使わずに、開発者用コマンドプロンプトを用いて試そう

作成例

//アレンジ演習:p.198 main02.cs
using System;
class main02 {
    public static int Main(string[] args) { //コマンドライン引数を受け取り、整数値を返すMain
        if (args.Length != 1) {
            Console.WriteLine("return -1"); //【追加】
            return -1;
        }
        if (!Char.IsDigit(args[0][0])) { //【変更】
            Console.WriteLine("return -2"); //【追加】
            return -2;
        }
        Console.WriteLine("return {0}", int.Parse(args[0])); //【追加】
        return int.Parse(args[0]);
    }
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です