カウンセリングエンジニア

産業カウンセラーの有資格者が発信します。カウンセリング、マネジメント、Unityあたりの内容多めで構成する予定です

C# ref outの違いとそれぞれの使い所

概要

refとoutについて勉強がてらまとめます。

refとoutの定義

まずはrefとoutそれぞれの定義をMSDNから確認します。

ref

ref キーワードは、引数を値ではなく、参照によって渡すことを示します。 参照渡しで渡すことにより、呼び出されたメソッドの引数に対する変更が、呼び出し元のメソッドに反映されます。

madnより引用

out

out キーワードによって、参照により引数が渡されます。 これは、ref キーワードと似ていますが、ref では変数を初期化してから渡す必要があります。out パラメーターを使用するには、メソッド定義と呼び出し元のメソッドの両方で out キーワードを明示的に使用する必要があります。

madnより引用

これを見る限りrefもoutも参照渡しだが、引数の渡し方に違いがあるようです。
コードで確認してみます

public class RefOutSample
{
    public class Hoge
    {
        public string Name;
    }
    
    public void RefSample1(ref Hoge hoge)
    {
        hoge.Name = "refのサンプルメソッドです";
    }

    // outは中で初期化してから使う必要があるためこのメソッドはエラーになります.
    public void OutSample1(out Hoge hoge)
    {
        hoge.Name = "outのサンプルメソッドです";
    }

    // このメソッドのように中で一度初期化するとエラーになりません
    public void OutSample2(out Hoge hoge)
    {
        hoge =  new Hoge();
        hoge.Name = "outのサンプルメソッドです";
    }

    void Main()
    {
        Hoge hoge;
        // refは変数を初期化してから渡す必要があるためこの呼出はエラーになります
        RefSample1(ref hoge);
        // outは大丈夫です
        OutSample1(out hoge);
        OutSample2(out hoge);
    }
}

それぞれの使い所

上記から、 refは渡した変数に直接操作をしたい時
outはメソッドの中の結果を外に渡したい時に使うのが良さそうです。

out

outはTryParseの様な判定をboolで返しつつ結果も返して欲しい場面で使えそうです。

    void Sample()
    {
        string a = "100";
        int b;
        
        bool result = int.TryParse(a, out b);
    }

ref

refはMathの計算系で使うのが良さそうかなと思い、
下記のようなコードを書いてみました。

void Pow(ref int x)
{
    x = x * x;
}

void Main()
{
    int i = 10;
    Pow(ref i);
}

うーん。。微妙ですね^^;

int Pow(ref int x)
{
    x = x * x;
}

void Main()
{
    int i = 10;
    i = Pow(i);
}

の方がわかりやすい気がします。
誰かrefの良い使い所を知っている方いたら教えてください。。

まとめ

outは少し使い所わかったけど、refについては疑問が残ったまま。。
どちらにせよ基本的には値渡しにしてreturnで値を返してくれたほうがわかりやすいので、
そうした設計を心がけるようにします。