値型と参照型

プログラミングC# 第6版 3.4


ここはC++を勉強した人は注意が必要ですね。newはメモリの確保でポインタだ!みたいな固定概念を持ってるとC#では躓くと思います。

まず参照型というのがどういうものが確認してみましょう。

using System;

class CSample {
    public int foo;
}

class Program {
    static void Main () {
        CSample cobj1 = new CSample();
        cobj1.foo = 0;
        
        CSample cobj2 = cobj1;
        
        cobj2.foo = 100; // cobj2だけ書き換えてみる
        
        Console.WriteLine(cobj1.foo);
        Console.WriteLine(cobj2.foo);
    }
}
$ main
100
100

実行結果が0、100にならないのはCSampleが参照型だからです。これはぶっちゃけC++プログラマなら想定内の挙動でしょう。

次は値型の確認です。

using System;

struct CSample {
    public int foo;
}

class Program {
    static void Main () {
        CSample cobj1 = new CSample();
        cobj1.foo = 0;
        
        CSample cobj2 = cobj1;
        
        cobj2.foo = 100; // cobj2だけ書き換えてみる
        
        Console.WriteLine(cobj1.foo);
        Console.WriteLine(cobj2.foo);
    }
}
$ main
0
100

となります。あれ?どこが変わったの?という感じでしょうが、変わったのは「class CSample」→「struct CSample」の部分のみです。

つまりclassで定義した型は参照型で、structで定義した型は値型になるということですね。

C++プログラマからするとstructって構造体でしょ!と思うかもしれませんがC#では値型用のクラスみたいな感じだと思った方がいいみたいです。

C++プログラマからするとnewしてるのに値型かよ!と思うかもしれませんがC#ではnewの挙動はまったく別物だと思った方がいいみたいです。

先入観で物事を考えずにC#はこういう仕様だと素直に受け入れるようにしましょう。

ぶっちゃけそこさえ気をつければC++よりも扱いやすいと思うので要は慣れでしょうねぇ。