C# 参照渡し in ref out 違い

今回は、C# における関数の引数について紹介していきます。

関数の引数には、値渡しと参照渡しというのがありますが、参照渡しの3つ「in」「ref」「out」について紹介していきます。

値渡しと参照渡しについてわからない方は、先にこちらを参考にしてみてください。

ちなみに「in」「ref」「out」はそれぞれこんなイメージになっています。

in:読み取り専用
ref:関数に渡された引数を更新する
out:関数の結果を引数に格納する

refによる参照渡し

それでは、まず一番よく使うrefについて、見ていきましょう。

refは、関数を呼び出すときの引数に値して値を更新する処理を記載するときに使用します。

例を見てみましょう。

private void FrmInRefOut_Load(object sender, EventArgs e)
{
    //値設定
    string str = "デフォルトの値";

    //関数呼び出し
    CallMsgRef(ref str);

    //メッセージボックス呼び出し
    MessageBox.Show(str);
}

private void CallMsgRef(ref string msg)
{
    msg = "refによる参照渡し";
}

フォームのロード処理でメッセージボックスを呼び出しているのですが、メッセージボックスに表示する文字列を、関数で変更しています。

この時に呼び出している関数の引数をrefと宣言することで更新することができます。

結果

 

この時に、refに利用する変数には値を格納してから渡さないとエラーになるので注意してください。
下の画像では、変数「str」に初期値を格納せずに処理を記載しましたが、エラーになります。

refのイメージは、更新ですので、もともと値を設定されているものを変更するときに利用しましょう。

 

outによる参照渡し

続いて、outを見ていきましょう。

outは、refとは違い、もともと値を設定していないものに、値を設定するときに使用します。

例を見ていきましょう。

private void FrmInRefOut_Load(object sender, EventArgs e)
{
    //値設定
    string str;

    //関数呼び出し
    CallMsgOut(out str);

    //メッセージボックス呼び出し
    MessageBox.Show(str);
}

private void CallMsgOut(out string msg)
{
    msg = "outによる参照渡し";
}

 

4行目のように、変数「str」の文字を初期化せず、関数を呼び出しましょう。

先ほど、「ref」ではエラーが発生していましたが、「out」に変更するとうまくいきましたね。

結果

outは、空の変数に対して、関数の結果を出力するときに使用しましょう。

 

inによる参照渡し

最後にinによる参照渡しを紹介していきます。

inによる参照渡しは、読み取り専用なので、引数で渡した値を更新することはできません。

private void FrmInRefOut_Load(object sender, EventArgs e)
{
    //値設定
    string str = "デフォルトの値";

    //関数呼び出し
    CallMsgIn(in str);

    //メッセージボックス呼び出し
    MessageBox.Show(str);
}

private void CallMsgIn(in string msg)
{
    msg = "inによる参照渡し";
}  

下の画像のようにエラーが発生してしまいます。

読み取り専用なのに、値を更新しようとしているためエラーが発生しています。

このように、「in」は読み取り専用の引数ということが、開発者にすぐわかるようになっています。

なので、ほかの人がソースを見たときに、inの引数は、値が更新されていないことをすぐに理解することができるので、影響範囲などがわかりやすくなりますね。

 

まとめ

C#の参照渡しについて今回は詳しく見ていきました。

「in」と「ref」と「out」の違いはとても大切なので、しっかりと理解していきましょう。

in:読み取り専用
ref:関数に渡された引数を更新する
out:関数の結果を引数に格納する

 

C#の記事一覧

おすすめの記事