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回
ディスカッション
コメント一覧
まだ、コメントがありません