[C#] メソッドの引数

C#

ソースを読んでて引数によくわからんoutやらrefがあったので調べてみました
C#でメソッドを扱うとき、Javaと違う点がある。

・まず普通にJavaと同じような使い方

using System;
namespace hwapp
{
    class Program
    {
        static void Main()
        {
            int a = 100;
            a = TimesMethod(a);
            Console.WriteLine(a);     //200が出力
        }      
        static int TimesMethod(int i)
        {
            i = i * 2;
            return i;
        }
    }    
}      

Mainメソッドから1をTimesMethodメソッドに渡して2倍して返して出力します。
うん。まあ、Javaからしたら普段通りの感じですね。
これは int i の値を渡しているから、値渡しです。

・C#には参照渡しと呼ばれるものがあります。

using System;

namespace hwapp
{
    class Program
    {
        static void Main()
        {
            int a = 100;
            Console.WriteLine(a);    //100が出力
            TimesMethod(ref a);
            Console.WriteLine(a);    //200が出力
        }      
        static void TimesMethod(ref int i)
        {
            i = i * 2;
        }
    }    
}

先ほどより少し変更があります。
TimesMethod()の戻り値の設定がなくなったのと、TimesMethodの()の中ですね。
こちらの引数の前に”ref”というキーワードがあります。つまり参照です。
定義と呼び出し両方に書きます。つまり使う側も使われる側も、普段の値渡しと違って参照だからね!!って確かめあっています。

で、どうなっているかというと、メソッドの中身はほぼ同じなのですが、まずMain()の中で int a を定義して出力しています。当たり前のように100が出力されているのがわかると思います。
そのあと、TimesMethodを呼び出して a を渡しています。そして a を出力すると200が出力されます。

ではよく見てみると、、

TimesMethod(ref a);

このように呼び出しに引数として a を渡しているだけです。
そもそもTimesMethod()に戻り値の設定はありません。
その時に先ほどの”ref”もつけることによって値そのものを渡しているのではなく a の参照を渡します。なのでTimesMethodで2倍になった a を出力すると200が出力されることになります。

ん〜〜〜。Javaしか知らないから、なんだか新しい感じがしますね笑

参照渡しを使うとメソッド内からメソッド外の変数を書き換えることができ、戻り値の代わりとして使うことができます。問題としては、、

・変数の初期化をしないといけない
・先ほどでいうとTimesMethod()で代入をしなくてもコンパイルエラーにならない

という、ちょっと扱いにくい問題があります。
これを解消する出力パラメーター(出力引数)というのがあります。←名前は怪しい。。
では見てみると

using System;

namespace hwapp
{
    class Program
    {
        static void Main()
        {
        /*    int a = 100;
            Console.WriteLine(a);    //100が出力
        ここは省略*/
  
            int a;                   //"out"をつけると初期化しなくてよい
            TimesMethod(out a);
            Console.WriteLine(a);    //100が出力
        }      
        static void TimesMethod(out int i)
        {
            i = 100;                 //"out"を使った場合必ず代入する
        }
    }    
}

さて、何が変わったかというと先ほどは”ref”をつけましたが”out”が代わりにつくようになりました。
先ほどの問題点が解消され

・変数の初期化をしなくてもよい
・先ほどでいうとTimesMethod()で代入しないといけない

というルールになります。

・・・・・・・・・・じゃあ、これ、いつ使うの????

てなりますよね。わかります笑
“return”で返せる戻り値の数は何個でしょう????(Java的に考えて)

そうですね。1つです。
でもこの出力パラメータを使用すると複数の戻り値として設定ができます

さらにC#7になって色々実装されているようですが勉強したての身としてはまだ難しいのでどこかで笑

コメント

タイトルとURLをコピーしました