0Pricing
C# Academy · レッスン

値型と参照型

それぞれがどのように格納され、コピーされるかを確認します。

「値型と参照型」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。

2つの型の分類

C# の型は、value type(int、double、bool、struct)とreference type(クラス、文字列、配列)に分けられます。これらは、データの格納方法とコピー方法が異なります。

using System;

class Program
{
    static void Main()
    {
        int valueType = 5;          // value type
        int[] referenceType = { 1, 2, 3 };  // reference type
        Console.WriteLine(valueType + ", length " + referenceType.Length);
    }
}

値型はデータを保持する

値型の変数は、データを直接保持します。通常、値型のデータは stack に格納されるか、包含するオブジェクト内にインラインで格納されます。

using System;

class Program
{
    static void Main()
    {
        int a = 10;
        double b = 3.14;
        bool c = true;
        Console.WriteLine(a + ", " + b + ", " + c);
    }
}

参照型はアドレスを保持する

参照型の変数は、heap に格納されたデータへの reference(アドレス)を保持します。変数とオブジェクトは別々のものです。

using System;

class Box { public int Value; }

class Program
{
    static void Main()
    {
        Box b = new Box();   // b refers to a heap object
        b.Value = 42;
        Console.WriteLine(b.Value);
    }
}

コピーのセマンティクス: 値型

値型を代入するとデータがコピーされます。コピーを変更しても、元の値には決して影響しません。

using System;

class Program
{
    static void Main()
    {
        int a = 1;
        int b = a;   // copy
        b = 99;
        Console.WriteLine("a=" + a + ", b=" + b);
    }
}

コピーの意味論:参照型

参照型を代入すると、オブジェクトではなく参照がコピーされます。そのため、両方の変数が同じオブジェクトを指します。

using System;

class Box { public int Value; }

class Program
{
    static void Main()
    {
        Box a = new Box { Value = 1 };
        Box b = a;   // same object
        b.Value = 99;
        Console.WriteLine("a.Value=" + a.Value + ", b.Value=" + b.Value);
    }
}

構造体は値型

定義したstructは値型なので、intと同じように代入時にコピーされます。

using System;

struct Point { public int X, Y; }

class Program
{
    static void Main()
    {
        Point p1 = new Point { X = 1, Y = 2 };
        Point p2 = p1;   // full copy
        p2.X = 99;
        Console.WriteLine("p1.X=" + p1.X + ", p2.X=" + p2.X);
    }
}

メソッドへの引き渡し

既定では、値型はコピーによって渡され、参照型では参照のコピーが渡されます。そのため、メソッドは呼び出し元から見えるクラスオブジェクトを変更できますが、単純な int は変更できません。

using System;

class Counter { public int N; }

class Program
{
    static void BumpInt(int x) { x++; }
    static void BumpObj(Counter c) { c.N++; }

    static void Main()
    {
        int i = 0;
        BumpInt(i);
        var c = new Counter();
        BumpObj(c);
        Console.WriteLine("i=" + i + ", c.N=" + c.N);
    }
}

null と参照型

​​null(オブジェクトが存在しない状態)にできるのは参照型だけです。値型は、?を付けて null 許容として宣言しない限り、常に値を保持します。

using System;

class Program
{
    static void Main()
    {
        string text = null;        // reference type can be null
        int? maybe = null;          // nullable value type
        Console.WriteLine((text == null) + ", " + (maybe == null));
    }
}

等価性の違い

値型では、==はデータを比較します。参照型では、オーバーライドされていない限り、==は通常、同一性(同じオブジェクトかどうか)を比較します。

using System;

class Program
{
    static void Main()
    {
        int a = 5, b = 5;
        Console.WriteLine("ints: " + (a == b));   // True - same value

        object o1 = new object();
        object o2 = new object();
        Console.WriteLine("objects: " + (o1 == o2));   // False - different identity
    }
}

既定値

値型にはゼロに相当する既定値(0、false)があり、参照型の既定値はnullです。

using System;

class Program
{
    static void Main()
    {
        int defaultInt = default;
        bool defaultBool = default;
        string defaultString = default;
        Console.WriteLine(defaultInt + ", " + defaultBool + ", null? " + (defaultString == null));
    }
}

まとめ

型が値型か参照型かを知っていれば、コピーの動作、null 許容性、メソッドによる変更の可否を予測できます。これは、正しくバグのないコードを書くうえで重要です。

using System;

struct Money { public decimal Amount; }
class Wallet { public decimal Amount; }

class Program
{
    static void Main()
    {
        Money m1 = new Money { Amount = 10 };
        Money m2 = m1; m2.Amount = 99;

        Wallet w1 = new Wallet { Amount = 10 };
        Wallet w2 = w1; w2.Amount = 99;

        Console.WriteLine("Money copy: " + m1.Amount + " (independent)");
        Console.WriteLine("Wallet ref: " + w1.Amount + " (shared)");
    }
}

確認問題

値型と参照型についての理解度を確認しましょう。

要点の復習

値型(int、double、bool、構造体)はデータを直接保持し、代入時にコピーされます。一方、参照型(クラス、文字列、配列)はヒープ上のオブジェクトへの参照を保持し、参照をコピーします。既定で null にできるのは参照型だけであり、代入時の動作と等価性の判定方法も両者で異なります。

using System;

struct V { public int N; }
class R { public int N; }

class Program
{
    static void Main()
    {
        V v1 = new V { N = 1 }; V v2 = v1; v2.N = 9;
        R r1 = new R { N = 1 }; R r2 = r1; r2.N = 9;
        Console.WriteLine(v1.N + " vs " + r1.N);
    }
}

よくある質問

「値型と参照型」レッスンは無料ですか?

はい。「値型と参照型」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。

「値型と参照型」で何を学びますか?

それぞれがどのように格納され、コピーされるかを確認します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「値型と参照型」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 値型と参照型
  2. ボックス化とボックス化解除
  3. 暗黙的変換と明示的変換
  4. Convertクラスと解析
← C# Academyに戻る