C#のclassとstructの違いを「メソッド引数」で体感しよう!

C#には「クラス(class)」と「構造体(struct)」という2つのデータ型の定義方法があります。見た目は似ていても、その内部的な仕組みは大きく異なります。

今回は、**「メソッドの引数として渡したときにどう挙動が変わるのか?」**という観点から、違いを実際のコードとともに見てみましょう。


サンプル1:class(参照型)の場合

class Program
{
    static void Main()
    {
        var king = new Card(CardSuit.Spade, 13);
        Console.WriteLine($"Suit:{king.Suit}, Number:{king.Number}");

        ChangeToAce(king);

        Console.WriteLine($"Suit:{king.Suit}, Number:{king.Number}");
    }

    private static void ChangeToAce(Card card)
    {
        card = new Card(CardSuit.Club, 1);
    }
}

enum CardSuit
{
    Club, Spade, Heart, Diamond
}

class Card
{
    public CardSuit Suit { get; set; }
    public int Number { get; set; }

    public Card(CardSuit suit, int number)
    {
        Suit = suit;
        Number = number;
    }
}

実行結果

Suit:Spade, Number:13
Suit:Spade, Number:13

解説

  • Card は class なので「参照型」。
  • 参照型の変数は、実体のアドレスを保持する変数です。
  • king は Card オブジェクトのアドレスを保持しています。
  • ChangeToAce(king) で渡されるのは アドレスのコピー
  • card = new Card(…) によって参照先を変更しても、king の参照先は変わらず → 出力は変化なし。

ポイント

参照型の変数をメソッドに渡すと、アドレスのコピーが渡される。

メソッド内で新しいオブジェクトを代入しても、元の変数には影響しない。


サンプル2:struct(値型)の場合

class Program
{
    static void Main()
    {
        var king = new Card(CardSuit.Spade, 13);
        Console.WriteLine($"Suit:{king.Suit}, Number:{king.Number}");

        ChangeToAce(king);

        Console.WriteLine($"Suit:{king.Suit}, Number:{king.Number}");
    }

    private static void ChangeToAce(Card card)
    {
        card = new Card(CardSuit.Club, 1);
    }
}

enum CardSuit
{
    Club, Spade, Heart, Diamond
}

struct Card
{
    public CardSuit Suit { get; set; }
    public int Number { get; set; }

    public Card(CardSuit suit, int number)
    {
        Suit = suit;
        Number = number;
    }
}

実行結果

Suit:Spade, Number:13
Suit:Spade, Number:13

解説

  • Card は struct なので「値型」。
  • 値型の変数は、データそのものを保持しています。
  • ChangeToAce(king) で渡されるのは kingの完全なコピー
  • card = new Card(…) はコピーに対する代入 → 元の king には影響なし。

ポイント

値型の変数をメソッドに渡すと、完全な複製(値渡し)になる。

コピー先をいじっても、元の変数には何の影響もない。


まとめ:classとstructの「渡し方の違い」

観点class(参照型)struct(値型)
変数の中身オブジェクトのアドレス(参照)実データそのもの
メソッド渡し参照のコピー(アドレスを渡す)データのコピー(値を渡す)
代入の影響新しいオブジェクトを代入しても元に影響なしコピーに対する操作なので元に影響なし

✅ 補足:元の変数を変更したい場合

class の場合

void ChangeToAce(Card card)
{
    card.Number = 1;  // 中身を変更すれば反映される
}

struct の場合

void ChangeToAce(ref Card card)
{
    card = new Card(CardSuit.Club, 1);  // ref を使えば元の変数自体を変更できる
}

終わりに

C# の class と struct の違いは、初学者がつまずきやすいポイントですが、「メソッド引数に渡したときの挙動」で見てみると、とてもわかりやすくなります。

  • 値型(struct)はコピーされる
  • 参照型(class)はアドレスのコピーが渡る

という原則をおさえながら、使い分けていきましょう。

訪問数 11 回, 今日の訪問数 5回