C# Reference and Value Types 参照型と値型の違い

C#は以下のようにデータタイプがあり、データの保存方法が異なる。methodにデータを渡したときの挙動が変わるので注意

  1. Value Type (int, float, bool etc)
  2. Reference Type (string, array, class etc)

基本的にValue TypeはMethodにわたすと新しい別の変数を作るので、メソッド内で変数を変更しても、本来の変数に影響を与えることはない。逆にReference TypeはあくまでReferenceを渡しているので別のメソッドで変数に変更を加えると、本来の変数にも影響を与える。ただし、StringはReference TypeだがImmutableで変更することができず、別のメソッドにわたすと新しい変数を作り直すので本来の変数に影響を与えないので注意。詳しくは以下参照

public class Forecast
    {
        public int Temperature { get; set; }
        public int Pressure { get; set; }
    }
    class Program
    {
        public static void ChangeTheString(string weather){ weather = "sunny"; }
        public static void ChangeTheString2(ref string weather){ weather = "sunny"; }
        public static void ChangeTheArray(string[] rainyDays) { rainyDays[1] = "Sunday"; }
        public static void ChangeTheClassInstance(Forecast forecast) { forecast.Temperature = 35; }
        static void Main(string[] args)
        {
            String weather = "rainy";
            ChangeTheString(weather);
            Console.WriteLine("The weather is " + weather); // rainy
            ChangeTheString2(ref weather);
            Console.WriteLine("The weather is " + weather); // sunny

            string[] rainyDays = new[] { "Monday", "Friday" };
            ChangeTheArray(rainyDays);
            Console.WriteLine("The rainy days were on " + rainyDays[0] + " and " + rainyDays[1]); // Monday and Sunday

            Forecast forecast = new Forecast { Pressure = 700, Temperature = 20 };
            ChangeTheClassInstance(forecast);
            Console.WriteLine("The temperature is " + forecast.Temperature + " degree"); // The temperature is 35 degree
        }
    }

intはValue Typeなので普通にメソッドに渡しただけだと変数が変更されないが、Reference Typeとして渡すことが可能。その場合、元の変数も影響を受ける


        public static void ChangeNumber(int? number){number = 100;}
        public static void ChangeNumber2(ref int number){ number = 100;}
        static void Main(string[] args)
        {
            int? number = 50;
            ChangeNumber(number);
            Console.WriteLine(string.Format("Number is {0}", number)); // 50
            //int number2;
            //ChangeNumber2(ref number2); // Received error - 'use of unassigned local number 2'
            //Console.WriteLine(string.Format("Number is {0}", number2)); // 100
            int number3 = 50;
            ChangeNumber2(ref number3);
            Console.WriteLine(string.Format("Number is {0}", number3)); // 100
        }