パハットノート

主にUnity(C#)を中心としたプログラムの備忘録

C# ref, in, outの使い方





refの使い方

概要

refを付けると関数内で値の上書きができるようになります。
関数内での書き換えたい値が1つなら返り値を使えばよいですが、2つ以上だと返り値だけだと難しいです。その際に重宝します。


使用例

ソースコード

using System;

public class Sample
{
    static void func1(ref int a)
    {
        a = 5;
    }

    public static void Main()
    {
        int a = 2;
        Console.WriteLine($"a = {a}\n");

        //func1で渡す
        func1(ref a);
        Console.WriteLine($"func1で書き換え後\na = {a}");
    }
}



実行結果

func1で書き換え後
a = 5



補足

List型などはrefを付けなくても関数内で値を書き換えることができます。

ソースコード

using System;
using System.Collections.Generic;

public class Sample2
{ 
    //リストの中身をすべて0に書き換える
    static void func2(List<int> a)
    {
        //すべて0に書き換える
        for (int i = 0; i < a.Count; i++)
        {
            a[i] = 0;
        }
    }

    public static void Main()
    {
        List<int> list1 = new List<int>() { 1, 2, 3, 4, 5 };

        //表示
        Console.Write("list1 = {");
        for (int i = 0; i < list1.Count; i++)
        {
            Console.Write($"{list1[i]}, ");
        }
        Console.WriteLine("}");

        //func2の呼び出し
        func2(list1);

        //表示
        Console.Write("list1 = {");
        for (int i = 0; i < list1.Count; i++)
        {
            Console.Write($"{list1[i]}, ");
        }
        Console.WriteLine("}");
    }
}


実行結果

list1 = {1, 2, 3, 4, 5, }
list1 = {0, 0, 0, 0, 0, }





outの使い方

概要

outでもrefと同様に関数内で値の上書きができるようになります。
関数呼び出し前の初期化が不要であることがrefとの違いです。
refを使っても同じことができますが、うまく使えばrefよりきれいにコードをかけるようになります。


使用例

先ほどのソースコードをoutを使って書き換えると次のようになります。

ソースコード

using System;

public class Sample3
{
    static void func3(out int a)
    {
        a = 5;
    }

    public static void Main()
    {
        //func1で渡す
        func3(out int a);
        Console.WriteLine($"func3呼び出し後\na = {a}");
    }
}


実行結果

func3呼び出し後
a = 5





inの使い方

概要

refやoutとは逆に呼び出した関数内での書き換えを禁止します。
inが付いた引数を書き換えようとすると実行時にエラーが生じます。
Listなどを引数にするけど書き換えたくないなどのときに重宝します。


ソースコード(実行するとエラー発生)

using System.Collections.Generic;

public class Sample4
{ 
    //エラー(inを付けているので書き換えが不可)
    static void func2(in List<int> a)
    {
        //すべて0に書き換える
        for (int i = 0; i < a.Count; i++)
        {
            a[i] = 0;
        }
    }

    public static void Main()
    {
        List<int> list1 = new List<int>() { 1, 2, 3, 4, 5 };

        //func2の呼び出し
        func2(list1);
    }
}