C#
 Computer >> コンピューター >  >> プログラミング >> C#

C# 7.0のrefローカル変数とref戻り値とは?基本の仕組みと実例をわかりやすく解説

C# 7.0で導入された「ref戻り値(ref return)」は、メソッドが値そのものではなく、変数への参照を返すことを可能にする機能です。

呼び出し側では、返された変数を値として扱うことも、参照として扱うことも自由に選択できます。さらに、返された値への参照そのものを持つ新しい変数を作成することもでき、これを「refローカル変数(ref local)」と呼びます。

通常の代入では元の配列は変更されない

まず、通常の代入を行った場合の挙動を見てみましょう。以下の例では、color 変数の値を変更しても、元の colors 配列には一切影響しません。

コード例

class Program{
    public static void Main(){
        var colors = new[] { "blue", "green", "yellow", "orange", "pink" };
        string color = colors[3];
        color = "Magenta";
        System.Console.WriteLine(String.Join(" ", colors));
        Console.ReadLine();
    }
}

出力結果

blue green yellow orange pink

これは、colors[3] の値がコピーされて color に代入されるためです。コピー先を書き換えても、元の配列要素はそのまま残ります。

refローカル変数を使って元の配列を直接書き換える

そこで活躍するのが refローカル変数です。変数宣言に ref キーワードを付けることで、配列要素そのものへの参照として変数を扱えます。

コード例

public static void Main(){
    var colors = new[] { "blue", "green", "yellow", "orange", "pink" };
    ref string color = ref colors[3];
    color = "Magenta";
    System.Console.WriteLine(String.Join(" ", colors));
    Console.ReadLine();
}

出力結果

blue green yellow Magenta pink

このように、ref string color = ref colors[3]; と記述すると、color は colors[3] のエイリアス(別名)として機能し、代入によって元の配列要素が直接更新されます。

ref戻り値(ref return)とは

続いて、メソッドから参照を返す「ref戻り値」について見ていきましょう。

まず、通常のメソッドで値を返した場合の例です。やはり元の配列には影響しません。

コード例(通常の戻り値)

class Program{
    public static void Main(){
        var colors = new[] { "blue", "green", "yellow", "orange", "pink" };
        string color = GetColor(colors, 3);
        color = "Magenta";
        System.Console.WriteLine(String.Join(" ", colors));
        Console.ReadLine();
    }
    public static string GetColor(string[] col, int index){
        return col[index];
    }
}

出力結果

blue green yellow orange pink

次に、メソッドの戻り値の型と return 文の両方に ref を付けた場合の例です。

コード例(ref戻り値)

class Program{
    public static void Main(){
        var colors = new[] { "blue", "green", "yellow", "orange", "pink" };
        ref string color = ref GetColor(colors, 3);
        color = "Magenta";
        System.Console.WriteLine(String.Join(" ", colors));
        Console.ReadLine();
    }
    public static ref string GetColor(string[] col, int index){
        return ref col[index];
    }
}

出力結果

blue green yellow Magenta pink

メソッド側で public static ref string GetColor(...) と宣言し、return ref col[index]; とすることで、値ではなく配列要素への参照が返されます。呼び出し側でも ref string color = ref GetColor(colors, 3); のように受け取ることで、color への代入が元の配列に反映されるようになります。

まとめ

  • refローカル変数:ローカル変数を他の変数(配列要素など)への参照として宣言できる機能。
  • ref戻り値:メソッドが変数への参照を返せる機能。呼び出し側で ref を付けて受け取ると、元のデータを直接操作できる。
  • 大きな構造体のコピーコストを避けたい場合や、配列・コレクション内の特定要素を効率的に書き換えたい場合に特に有効です。
  1. C#のrefパラメーターとoutパラメーターの違いとは?使い分けのポイントを解説

    C#には、メソッドに引数を渡す際に変数そのものへの参照を渡すための仕組みとして、「refパラメーター」と「outパラメーター」の2種類が用意されています。どちらも呼び出し元の変数の値をメソッド内から直接操作できる点は共通していますが、初期化の要否や代入のルール、想定される用途に違いがあります。本記事では、サンプルコードを交えながら、両者の違いをわかりやすく解説します。 refパラメーター(参照パラメーター)とは refパラメーターは、変数のメモリ上の場所(参照)をそのまま渡す仕組みです。通常の値渡しとは異なり、新しいストレージ領域は作成されません。そのため、メソッド内で行った変更が、そのまま呼

  2. C#の左シフト演算子(<<)と右シフト演算子(>>)の使い方を解説

    C#には、ビット単位でデータを操作するための「シフト演算子」が用意されています。代表的なものが左シフト演算子(<<)と右シフト演算子(>>)です。この記事では、それぞれの仕組みと具体的な使い方をサンプルコードとともに解説します。 左シフト演算子(<<)とは 左シフト演算子は、左側のオペランドの値を、右側のオペランドが指定したビット数だけ左に移動させる演算子です。 ビットが左にずれると、空いた下位ビットには0が埋められます。2進数では1桁左にずれるごとに値が2倍になるため、左シフトは「2のn乗倍」の計算としても利用できます。 右シフト演算子(>>)