C#の構造体(struct)とクラスの違いを徹底解説!初心者でも分かるC#オブジェクトの基本
生徒
「C#でstruct(ストラクト)とclass(クラス)ってどう違うんですか?」
先生
「いい質問ですね!C#では、struct(構造体)とclass(クラス)は見た目は似ていますが、動き方が大きく違います。」
生徒
「えっ、どういうことですか?同じように使えると思っていました…」
先生
「それでは、初心者でも分かるように、structとclassの違いを詳しく解説していきましょう!」
1. struct(構造体)とは?
C#のstruct(構造体)は、値型(バリュータイプ)のデータ構造です。値型とは、データそのものを直接扱うものです。
たとえば、intやdoubleなどの基本的なデータ型と同じように、structもメモリ上に直接値を保持します。値がコピーされるとき、まるごと複製されるという特徴があります。
以下は、簡単な構造体の例です。
struct Point
{
public int X;
public int Y;
}
このように、structは「座標の点」や「色」などの小さなデータを扱うのに適しています。
2. class(クラス)とは?
一方、class(クラス)は参照型(リファレンスタイプ)です。参照型では、変数にはデータそのものではなく、データの場所(アドレス)が保存されます。
つまり、あるクラスのインスタンスをコピーすると、実体は共有されるということになります。これが、構造体との大きな違いです。
クラスは、メソッド(処理)やプロパティ(データ)をまとめて定義できるので、大きくて複雑なデータを扱うときに向いています。
class PointClass
{
public int X;
public int Y;
}
3. 値型と参照型の違いとは?
ここで「値型」と「参照型」の違いを、初心者向けに荷物のやりとりにたとえてみましょう。
- struct(構造体)=値型は、「荷物を直接渡す」イメージ。コピーすれば、それぞれが別の荷物を持っています。
- class(クラス)=参照型は、「荷物の保管場所のメモを渡す」ようなもの。コピーしても、実際には同じ保管場所を見ているだけです。
この違いによって、データの扱い方やパフォーマンスにも影響があります。
4. structとclassの使い分けのポイント
C#では、構造体とクラスは状況によって使い分けるのが重要です。以下のような基準を覚えておくと便利です。
- データが小さくて単純 →
struct(構造体) - データが大きくて複雑 →
class(クラス) - コピーされたときに、別のデータとして扱いたい →
struct - コピーしても、同じものを共有したい →
class
5. 実際の違いをコードで見てみよう
構造体とクラスのコピー時の違いを、サンプルプログラムで見てみましょう。
構造体(struct)の例:
struct MyStruct
{
public int Value;
}
MyStruct a = new MyStruct();
a.Value = 10;
MyStruct b = a;
b.Value = 20;
Console.WriteLine("a.Value = " + a.Value);
Console.WriteLine("b.Value = " + b.Value);
実行結果:
a.Value = 10
b.Value = 20
→ bを変更してもaは影響を受けていません。これは、structが値型だからです。
クラス(class)の例:
class MyClass
{
public int Value;
}
MyClass a = new MyClass();
a.Value = 10;
MyClass b = a;
b.Value = 20;
Console.WriteLine("a.Value = " + a.Value);
Console.WriteLine("b.Value = " + b.Value);
実行結果:
a.Value = 20
b.Value = 20
→ bを変更すると、aも変わってしまいました。これは、classが参照型で、同じデータを見ているからです。
6. その他の違いもチェックしよう
structとclassには、ほかにも次のような違いがあります。
- 継承(けいしょう):
classは他のクラスを継承できますが、structはできません。 - デフォルトコンストラクタ:
structには自分でコンストラクタを定義することはできますが、引数なしのコンストラクタは自動で作られ、変更できません。 - null(ヌル)代入:
classの変数にはnullを代入できますが、structにはできません(ただしNullable<T>型を使えば可能)。
7. 実務でよく使われるのはどっち?
実際の開発では、クラス(class)が使われることが多いです。なぜなら、アプリケーションの多くは複雑なデータを扱うため、柔軟に機能を追加できるクラスが適しているからです。
一方、構造体(struct)は、軽量で処理が早いため、ゲーム開発やグラフィック処理など、パフォーマンスが求められる場面で使われることが多いです。
まとめ
C#のstruct(構造体)とclass(クラス)は、初心者が最初につまずきやすいテーマでありながら、プログラムの設計やデータ管理を考えるうえで非常に重要な概念です。ここまでの記事で学んだように、structは値型であり、classは参照型という根本的な違いがあります。値型はデータそのものをコピーしますが、参照型はデータの位置を共有するため、同じインスタンスを触っているように動作します。この特徴を理解することで、メモリの扱い方、パフォーマンス、データの独立性などをしっかり意識したプログラムが書けるようになります。
特に、初心者が誤解しやすいのが「コピーしたら別物なのか、同じ物なのか」という点です。小さくて軽いデータを扱いたいときは構造体が役立ち、複雑で大きな処理をまとめたいときにはクラスが適しています。実務で多く使われるのはクラスですが、構造体を適切に活用することで、無駄なメモリ使用を避けたり、高速な処理を実現したりすることが可能になります。
また、structには継承ができない、classはnullを扱えるなど、それぞれ特性にも違いがあります。こういった特性を知らずに使うと不具合の原因になりやすいため、今回の内容を一度整理して、自分のアプリケーションでどちらを選ぶべきか判断できるようにすることが大切です。structとclassは見た目が似ていても目的が異なるため、役割を意識した設計が求められます。
ここで、構造体とクラスの違いを明確に理解するために、記事で学んだ内容を応用したサンプルコードをひとつ紹介します。小規模データを扱うstructと、複雑な情報を扱うclassを同時に利用することで、それぞれの特徴と用途がよりはっきりと見えてきます。
サンプルプログラム:構造体とクラスの特徴を活かしたデータ管理
下記のプログラムでは、「座標」をstructで管理し、「キャラクター情報」をclassで扱っています。ゲーム開発や業務アプリなど、さまざまな場面でこの設計はよく使われます。
struct Position
{
public int X;
public int Y;
public Position(int x, int y)
{
this.X = x;
this.Y = y;
}
}
class Character
{
public string Name;
public Position Pos;
public Character(string name, Position pos)
{
this.Name = name;
this.Pos = pos;
}
public void Move(int x, int y)
{
this.Pos.X += x;
this.Pos.Y += y;
}
public void ShowInfo()
{
Console.WriteLine("キャラクター名: " + this.Name);
Console.WriteLine("現在位置: X=" + this.Pos.X + ", Y=" + this.Pos.Y);
}
}
class Program
{
static void Main()
{
Position start = new Position(0, 0);
Character hero = new Character("勇者", start);
hero.Move(5, 3);
hero.ShowInfo();
}
}
この例では、座標のように小さく独立したデータはstructで扱い、キャラクターのように複数の情報をまとめたい場合にはclassを使うことで、データの扱いが整理され、動作の意図も分かりやすくなります。構造体はコピーされることで独立した値として扱われるため、元の値に影響を与えません。一方、クラスは参照型であるため、どこからでも同じキャラクター情報を共有できます。これが、用途に応じた適切なデータの選び方につながります。
structとclassの正しい使い分けを理解することで、コードの読みやすさや保守性が劇的に向上します。また、開発中の不具合を未然に防ぎやすくなるため、初心者だけでなく経験者にとっても重要な基礎知識です。値型と参照型の仕組みを理解したうえで、適切な場面で使い分けることが今後のC#プログラミングの上達につながります。
生徒
「structとclassって名前が似ているから同じように考えていましたが、値型と参照型でこんなに違うんですね…!」
先生
「そうなんです。特にコピーしたときの挙動が大きく違うので、どちらを使うべきか考えることが大切ですよ。」
生徒
「たしかに、structは軽くて速いけど、classは複雑なデータをまとめられるって理解できました!」
先生
「用途によって選べるようになると、プログラムの設計が一気に楽になりますよ。今回のサンプルも良い例でしたね。」
生徒
「次からは“値型か参照型か”を意識して、structとclassをちゃんと使い分けてみます!」