C#のインスタンス化とは?newの使い方からエラー原因まで初心者向けに解説
はじめに
C#を学び始めると、かなり早い段階で「インスタンス化」という言葉に出会います。
C#Person person = new Person();
このようなコードを見て、「newって何?」「クラスを作っただけでは使えないの?」「インスタンスとオブジェクトは何が違うの?」と疑問に思う方も多いでしょう。
C#のインスタンス化とは、簡単にいうとクラスという設計図から、実際に使える実体を作ることです。C#ではクラスを定義しただけでは、まだデータを入れたりメソッドを呼び出したりできません。newを使ってインスタンスを作成することで、はじめてプログラム内で利用できるようになります。
この記事では、C#のインスタンス化について、newの基本的な使い方から、コンストラクター、エラーの原因、初心者が混同しやすい用語までわかりやすく解説します。
1. C#のインスタンス化とは?初心者向けにわかりやすく解説
1-1. インスタンス化とは「クラスから実体を作ること」
C#のインスタンス化とは、クラスをもとにオブジェクトを作成することです。
クラスは、データや処理をまとめた設計図のようなものです。たとえば、次のようなPersonクラスがあるとします。
C#class Person
{
public string Name;
public int Age;
}
この時点では、Personという「人を表す設計図」があるだけです。実際の人物データはまだ存在していません。
そこで、次のようにnewを使ってインスタンス化します。
C#Person person = new Person();
これにより、personという変数を通じて、Personクラスから作られた実体を扱えるようになります。
C#person.Name = "Taro";
person.Age = 20;
このように、クラスから実際に使えるオブジェクトを作ることを「インスタンス化」と呼びます。
1-2. クラス・オブジェクト・インスタンスの違い
C#の学習では、「クラス」「オブジェクト」「インスタンス」という言葉がよく出てきます。似た意味で使われることもありますが、厳密には少し違います。
クラスは設計図です。どのようなデータを持ち、どのような処理ができるかを定義します。
C#class Car
{
public string Color;
public void Drive()
{
Console.WriteLine("走ります");
}
}
インスタンスは、そのクラスから作られた実体です。
C#Car car = new Car();
このcarが、Carクラスから作られたインスタンスです。
オブジェクトは、プログラム上で扱う実体全般を指す言葉です。C#ではインスタンスのことをオブジェクトと呼ぶ場合も多いため、初心者のうちは「インスタンスはクラスから作られたオブジェクト」と理解しておくとよいでしょう。
1-3. なぜC#ではインスタンス化が必要なのか
C#でインスタンス化が必要な理由は、クラスを定義しただけでは実際のデータを保存する場所が用意されないからです。
たとえば、Personクラスを定義しても、それは「名前」や「年齢」を持てるというルールを決めただけです。
C#class Person
{
public string Name;
public int Age;
}
このクラスを使って、太郎さん、花子さん、佐藤さんのように複数の人物データを扱いたい場合、それぞれのインスタンスを作る必要があります。
C#Person taro = new Person();
Person hanako = new Person();
taro.Name = "Taro";
hanako.Name = "Hanako";
インスタンス化することで、同じクラスをもとに複数の独立したデータを作れます。これが、オブジェクト指向プログラミングの重要な考え方です。
1-4. インスタンス化するとメモリ上で何が起きるのか
C#でnewを使ってインスタンス化すると、メモリ上にオブジェクトを保存するための領域が確保されます。
C#Person person = new Person();
このコードでは、new Person()によってPersonクラスのインスタンスがメモリ上に作成されます。そして、そのインスタンスを参照するための情報がperson変数に代入されます。
重要なのは、person変数そのものにすべてのデータが入っているわけではなく、personはメモリ上にあるインスタンスを指しているという点です。
そのため、C#のクラスは「参照型」と呼ばれます。参照型では、変数には実体そのものではなく、実体の場所を示す参照が入ります。
2. C#でインスタンス化する基本構文
2-1. newを使ったインスタンス化の書き方
C#でクラスをインスタンス化する基本構文は次のとおりです。
C#クラス名 変数名 = new クラス名();
具体例は次のようになります。
C#Person person = new Person();
左側のPerson personは、Person型の変数personを宣言しています。右側のnew Person()は、Personクラスのインスタンスを作成しています。
つまり、この1行では「Person型の変数を用意し、そこに新しく作ったPersonインスタンスを代入する」という処理を行っています。
2-2. クラス名 変数名 = new クラス名(); の意味
次のコードを分解して考えてみましょう。
C#Person person = new Person();
Personは変数の型です。この変数にはPersonクラスのインスタンスを入れられます。
personは変数名です。作成したインスタンスを扱うための名前です。
new Person()は、Personクラスのインスタンスを新しく作成する処理です。
このように、C#のインスタンス化では「型」「変数名」「new」「コンストラクター呼び出し」が組み合わさっています。
2-3. インスタンス化したオブジェクトのメンバーにアクセスする方法
インスタンス化したオブジェクトのフィールド、プロパティ、メソッドには、ドット.を使ってアクセスします。
C#Person person = new Person();
person.Name = "Taro";
person.Age = 20;
Console.WriteLine(person.Name);
Console.WriteLine(person.Age);
メソッドを呼び出す場合も同じです。
C#class Person
{
public string Name;
public void SayHello()
{
Console.WriteLine($"こんにちは、{Name}です");
}
}
Person person = new Person();
person.Name = "Taro";
person.SayHello();
実行すると、次のように表示されます。
C#こんにちは、Taroです
このように、インスタンス化したオブジェクトは、変数名の後に.を付けて操作します。
2-4. varを使ったインスタンス化の書き方
C#では、varを使って型名を省略することもできます。
C#var person = new Person();
この場合、右側のnew Person()から、person変数の型はPersonだとコンパイラが判断します。
次の2つは、ほぼ同じ意味です。
C#Person person = new Person();
var person = new Person();
ただし、varは型がなくなるわけではありません。あくまでコンパイラが型を推論しているだけです。初心者のうちは、コードの意味を理解するために、まずは明示的に型を書く方法に慣れておくとよいでしょう。
2-5. object initializerを使った初期化方法
C#では、インスタンス化と同時にプロパティへ値を設定することもできます。これをオブジェクト初期化子、またはobject initializerと呼びます。
C#Person person = new Person
{
Name = "Taro",
Age = 20
};
この書き方は、次のコードと似た意味になります。
C#Person person = new Person();
person.Name = "Taro";
person.Age = 20;
オブジェクト初期化子を使うと、インスタンス作成時に初期値をまとめて設定できるため、コードが読みやすくなります。
C#class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
プロパティを持つクラスでは、object initializerがよく使われます。
3. newキーワードの使い方と役割
3-1. new演算子とは何か
C#のnewは、インスタンスを作成するためのキーワードです。一般的には「new演算子」と呼ばれます。
C#Person person = new Person();
newを使うと、指定した型の新しいインスタンスが作られます。そして、作られたインスタンスへの参照が返されます。
クラスだけでなく、配列や構造体、Listなどでもnewは使われます。
C#int[] numbers = new int[3];
List<string> names = new List<string>();
DateTime date = new DateTime(2024, 1, 1);
C#でオブジェクトを作る基本がnewです。
3-2. newでコンストラクターが呼び出される仕組み
new クラス名()と書くと、そのクラスのコンストラクターが呼び出されます。
C#Person person = new Person();
このコードでは、Personクラスのコンストラクターが実行されます。
コンストラクターとは、インスタンス化された直後に呼び出される特別なメソッドのようなものです。主に初期値の設定などに使います。
C#class Person
{
public Person()
{
Console.WriteLine("Personが作成されました");
}
}
このクラスをインスタンス化すると、コンストラクター内の処理が実行されます。
C#Person person = new Person();
結果は次のようになります。
C#Personが作成されました
3-3. 引数なしコンストラクターでインスタンス化する例
引数なしのコンストラクターは、次のように定義します。
C#class Person
{
public string Name;
public Person()
{
Name = "未設定";
}
}
インスタンス化するときは、次のように書きます。
C#Person person = new Person();
Console.WriteLine(person.Name);
実行結果は次のとおりです。
C#未設定
引数なしコンストラクターを使うと、インスタンス化した時点で共通の初期値を設定できます。
3-4. 引数ありコンストラクターでインスタンス化する例
コンストラクターには引数を持たせることもできます。
C#class Person
{
public string Name;
public int Age;
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
インスタンス化するときに、必要な値を渡します。
C#Person person = new Person("Taro", 20);
Console.WriteLine(person.Name);
Console.WriteLine(person.Age);
このように、引数ありコンストラクターを使うと、インスタンス作成時に必要な値を強制的に渡せます。
名前や年齢のように、オブジェクトを作る時点で必ず必要な値がある場合に便利です。
3-5. newを省略できるケースと省略できないケース
C#では、状況によってnewの型名を省略できる場合があります。
たとえば、C# 9以降では、左側の型が明確な場合にターゲット型のnewを使えます。
C#Person person = new();
これは次のコードと同じ意味です。
C#Person person = new Person();
ただし、すべての場面でnewそのものを省略できるわけではありません。クラスのインスタンスを作成する場合、基本的にはnewが必要です。
C#Person person; // 宣言だけ
person = new Person(); // インスタンス化
次のように、宣言しただけでメンバーにアクセスするとエラーになります。
C#Person person;
person.Name = "Taro"; // エラー
変数を宣言しただけでは、まだインスタンスが作られていないためです。
4. コンストラクターとインスタンス化の関係
4-1. コンストラクターとは何か
コンストラクターとは、クラスをインスタンス化したときに自動で呼び出される特別な処理です。
通常のメソッドとは違い、コンストラクターには戻り値の型を書きません。また、名前はクラス名と同じにします。
C#class Person
{
public Person()
{
Console.WriteLine("コンストラクターが呼び出されました");
}
}
このクラスをnewすると、コンストラクターが実行されます。
C#Person person = new Person();
コンストラクターは、フィールドやプロパティの初期化、必要な値の受け取り、初期設定などに使います。
4-2. デフォルトコンストラクターとは
クラスにコンストラクターを1つも定義していない場合、C#では自動的に引数なしのコンストラクターが用意されます。これをデフォルトコンストラクターと呼びます。
C#class Person
{
public string Name;
}
このクラスにはコンストラクターを書いていませんが、次のようにインスタンス化できます。
C#Person person = new Person();
ただし、自分でコンストラクターを定義すると、自動のデフォルトコンストラクターは作られなくなります。
C#class Person
{
public string Name;
public Person(string name)
{
Name = name;
}
}
この場合、次のコードはエラーになります。
C#Person person = new Person(); // エラー
なぜなら、引数なしコンストラクターが存在しないからです。
4-3. 自作コンストラクターを定義する方法
自作コンストラクターは、クラス名と同じ名前で定義します。
C#class Product
{
public string Name;
public int Price;
public Product(string name, int price)
{
Name = name;
Price = price;
}
}
インスタンス化するときは、コンストラクターに対応する引数を渡します。
C#Product product = new Product("ノートPC", 120000);
Console.WriteLine(product.Name);
Console.WriteLine(product.Price);
コンストラクターを使うことで、オブジェクトに必要な値を作成時に設定できます。
4-4. 複数のコンストラクターを使い分ける方法
C#では、引数の数や型が異なるコンストラクターを複数定義できます。これをコンストラクターのオーバーロードと呼びます。
C#class Person
{
public string Name;
public int Age;
public Person()
{
Name = "未設定";
Age = 0;
}
public Person(string name)
{
Name = name;
Age = 0;
}
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
使う側は、渡す引数によって呼び出されるコンストラクターが変わります。
C#Person p1 = new Person();
Person p2 = new Person("Taro");
Person p3 = new Person("Hanako", 25);
このように、状況に応じてインスタンス化の方法を変えられます。
4-5. コンストラクターで初期値を設定する実践例
実際の開発では、コンストラクターを使って「必ず必要な値」を設定することがよくあります。
C#class User
{
public string Name { get; }
public string Email { get; }
public User(string name, string email)
{
Name = name;
Email = email;
}
public void ShowProfile()
{
Console.WriteLine($"{Name}:{Email}");
}
}
このクラスでは、NameとEmailをコンストラクターで設定しています。
C#User user = new User("Taro", "taro@example.com");
user.ShowProfile();
このようにしておくと、名前やメールアドレスが未設定のUserインスタンスが作られにくくなります。
5. インスタンス化したオブジェクトの使い方
5-1. フィールドやプロパティに値を代入する
インスタンス化したオブジェクトには、フィールドやプロパティを通じて値を設定できます。
C#class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
使う側は次のように書きます。
C#Person person = new Person();
person.Name = "Taro";
person.Age = 20;
プロパティに値を代入することで、そのインスタンスが持つ状態を変更できます。
5-2. メソッドを呼び出す
インスタンス化したオブジェクトは、メソッドを呼び出して処理を実行できます。
C#class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}
インスタンス化してメソッドを呼び出します。
C#Calculator calculator = new Calculator();
int result = calculator.Add(3, 5);
Console.WriteLine(result);
実行結果は次のとおりです。
C#8
インスタンスメソッドは、基本的にインスタンスを作成してから呼び出します。
5-3. 複数のインスタンスを作ると値はどう分かれるのか
同じクラスから複数のインスタンスを作ると、それぞれが別々の値を持ちます。
C#Person p1 = new Person();
Person p2 = new Person();
p1.Name = "Taro";
p2.Name = "Hanako";
Console.WriteLine(p1.Name);
Console.WriteLine(p2.Name);
実行結果は次のようになります。
C#Taro
Hanako
p1とp2はどちらもPersonクラスから作られていますが、別々のインスタンスです。そのため、片方の値を変更しても、もう片方には影響しません。
5-4. 参照型としてのインスタンスの扱い方
C#のクラスは参照型です。参照型では、変数にオブジェクトそのものではなく、オブジェクトへの参照が入ります。
C#Person p1 = new Person();
p1.Name = "Taro";
Person p2 = p1;
p2.Name = "Hanako";
Console.WriteLine(p1.Name);
この結果は次のようになります。
C#Hanako
p2 = p1とすると、p1とp2は同じインスタンスを参照します。そのため、p2.Nameを変更すると、p1.Nameにも変更が反映されたように見えます。
実際には、同じオブジェクトを2つの変数から参照している状態です。
5-5. nullとインスタンス化済みオブジェクトの違い
nullは、変数がどのインスタンスも参照していない状態を表します。
C#Person person = null;
この状態でメンバーにアクセスすると、NullReferenceExceptionが発生します。
C#person.Name = "Taro"; // 実行時エラー
一方、インスタンス化済みのオブジェクトであれば、メンバーにアクセスできます。
C#Person person = new Person();
person.Name = "Taro";
C#のインスタンス化を理解するうえで、nullとnewされた状態の違いは非常に重要です。
6. C#でインスタンス化できない・エラーになる主な原因
6-1. クラス名や名前空間が間違っている
クラス名のスペルが間違っていると、インスタンス化できません。
C#Persn person = new Persn(); // エラー
正しくは次のように書きます。
C#Person person = new Person();
また、別の名前空間にあるクラスを使う場合は、usingが必要になることがあります。
C#using MyApp.Models;
または、完全修飾名で指定します。
C#MyApp.Models.Person person = new MyApp.Models.Person();
6-2. コンストラクターの引数が一致していない
クラスに引数ありコンストラクターしか定義されていない場合、引数なしでインスタンス化するとエラーになります。
C#class Person
{
public Person(string name)
{
}
}
Person person = new Person(); // エラー
正しくは、定義されているコンストラクターに合わせて引数を渡します。
C#Person person = new Person("Taro");
エラーが出たときは、コンストラクターの引数の数、型、順番を確認しましょう。
6-3. アクセス修飾子がprivateになっている
コンストラクターがprivateになっていると、クラスの外部からインスタンス化できません。
C#class Person
{
private Person()
{
}
}
Person person = new Person(); // エラー
外部からインスタンス化したい場合は、コンストラクターをpublicにします。
C#class Person
{
public Person()
{
}
}
privateコンストラクターは、シングルトンパターンやユーティリティクラスなど、外部から自由にインスタンス化させたくない場合に使われます。
6-4. abstractクラスを直接インスタンス化している
abstractが付いた抽象クラスは、直接インスタンス化できません。
C#abstract class Animal
{
public abstract void Speak();
}
Animal animal = new Animal(); // エラー
抽象クラスを使う場合は、継承した具象クラスを作成して、そのクラスをインスタンス化します。
C#class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("ワン");
}
}
Animal animal = new Dog();
animal.Speak();
抽象クラスは、共通のルールや処理を定義するための土台として使われます。
6-5. interfaceを直接インスタンス化している
interfaceも直接インスタンス化できません。
C#interface IAnimal
{
void Speak();
}
IAnimal animal = new IAnimal(); // エラー
interfaceは、実装すべきメソッドやプロパティの約束を定義するものです。実際に使うには、そのinterfaceを実装したクラスをインスタンス化します。
C#class Dog : IAnimal
{
public void Speak()
{
Console.WriteLine("ワン");
}
}
IAnimal animal = new Dog();
animal.Speak();
interface型の変数に、実装クラスのインスタンスを代入することは可能です。
6-6. staticクラスをインスタンス化しようとしている
staticクラスはインスタンス化できません。
C#static class MathHelper
{
public static int Add(int a, int b)
{
return a + b;
}
}
MathHelper helper = new MathHelper(); // エラー
staticクラスのメンバーは、クラス名から直接呼び出します。
C#int result = MathHelper.Add(3, 5);
staticクラスは、状態を持つインスタンスを作るのではなく、共通処理をまとめる用途で使われます。
6-7. NullReferenceExceptionが発生する原因
NullReferenceExceptionは、nullの変数に対してメンバーアクセスしようとしたときに発生します。
C#Person person = null;
Console.WriteLine(person.Name); // NullReferenceException
原因は、インスタンス化されていない変数を使っていることです。
修正するには、newでインスタンス化します。
C#Person person = new Person();
person.Name = "Taro";
Console.WriteLine(person.Name);
また、nullの可能性がある場合は、事前にチェックします。
C#if (person != null)
{
Console.WriteLine(person.Name);
}
6-8. 「型名が見つからない」「名前が現在のコンテキストに存在しない」エラーの原因
C#でインスタンス化しようとしたときに、「型または名前空間の名前が見つかりません」「現在のコンテキストに存在しません」というエラーが出ることがあります。
主な原因は次のとおりです。
クラス名のスペルが間違っている場合です。
C#Persn person = new Persn();
クラスが別の名前空間にあるのに、usingを書いていない場合です。
C#using MyApp.Models;
変数を宣言していないのに使っている場合です。
C#person.Name = "Taro"; // personを宣言していない
正しくは次のように、変数宣言とインスタンス化を行います。
C#Person person = new Person();
person.Name = "Taro";
エラー文を読むときは、「型が見つからない」のか「変数名が見つからない」のかを分けて考えると原因を特定しやすくなります。
7. インスタンス化が必要な場合・不要な場合
7-1. 通常のクラスはインスタンス化して使う
通常のクラスは、基本的にnewでインスタンス化してから使います。
C#Person person = new Person();
person.Name = "Taro";
フィールドやプロパティに個別の値を持たせたい場合、インスタンス化が必要です。
たとえば、ユーザー情報、商品情報、注文情報、キャラクター情報など、データごとに状態が異なるものはインスタンスとして扱うのが一般的です。
7-2. staticメンバーはインスタンス化せずに使う
staticメンバーは、インスタンスを作らずにクラス名から直接使います。
C#class MathHelper
{
public static int Add(int a, int b)
{
return a + b;
}
}
呼び出し方は次のとおりです。
C#int result = MathHelper.Add(10, 20);
staticメンバーは、特定のインスタンスに依存しない共通処理に向いています。
一方、インスタンスごとに異なる値を持ちたい場合は、staticではなく通常のインスタンスメンバーを使います。
7-3. 構造体のインスタンス化とクラスの違い
C#にはクラスのほかに構造体があります。構造体もインスタンス化できます。
C#struct Point
{
public int X;
public int Y;
}
Point point = new Point();
point.X = 10;
point.Y = 20;
クラスは参照型ですが、構造体は値型です。値型では、変数に値そのものが格納されるイメージです。
C#Point p1 = new Point();
p1.X = 10;
Point p2 = p1;
p2.X = 20;
Console.WriteLine(p1.X); // 10
Console.WriteLine(p2.X); // 20
クラスの場合は同じインスタンスを参照することがありますが、構造体では代入時に値がコピーされます。
7-4. 配列やListをインスタンス化する方法
配列もnewを使って作成します。
C#int[] numbers = new int[3];
numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
Listもインスタンス化して使います。
C#List<string> names = new List<string>();
names.Add("Taro");
names.Add("Hanako");
C#では、配列やListのようなコレクションも非常によく使います。特にList<T>は、要素数を後から増やせるため便利です。
C#var scores = new List<int> { 80, 90, 100 };
このように、コレクションの初期化にもnewが使われます。
7-5. UnityやASP.NETでインスタンス化の考え方が変わるケース
UnityやASP.NETでは、自分でnewしない場面も多くあります。
Unityでは、MonoBehaviourを継承したクラスを通常のようにnewして使うことは基本的にありません。
C#public class Player : MonoBehaviour
{
}
Unityでは、ゲームオブジェクトにコンポーネントとして追加したり、Instantiateを使って生成したりします。
C#Instantiate(prefab);
ASP.NETでは、コントローラーやサービスクラスをフレームワークやDIコンテナが生成することがあります。
C#public class UserController
{
private readonly UserService _userService;
public UserController(UserService userService)
{
_userService = userService;
}
}
このように、フレームワークがインスタンス化を代わりに行うケースもあります。ただし、基本的な考え方は同じで、「クラスから実体を作って使う」という点は変わりません。
8. C#のインスタンス化をサンプルコードで理解する
8-1. Personクラスをnewで作成する基本例
まずは、もっとも基本的な例です。
C#class Person
{
public string Name;
public int Age;
}
Person person = new Person();
person.Name = "Taro";
person.Age = 20;
Console.WriteLine(person.Name);
Console.WriteLine(person.Age);
このコードでは、Personクラスをnewでインスタンス化し、NameとAgeに値を代入しています。
実行結果は次のようになります。
C#Taro
20
8-2. コンストラクターで名前や年齢を初期化する例
次に、コンストラクターを使って初期化する例です。
C#class Person
{
public string Name;
public int Age;
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
Person person = new Person("Taro", 20);
Console.WriteLine(person.Name);
Console.WriteLine(person.Age);
この書き方では、インスタンス化と同時に名前と年齢を設定できます。
C#Taro
20
コンストラクターを使うと、必要な値を渡し忘れにくくなります。
8-3. 複数インスタンスを作って値の違いを確認する例
同じクラスから複数のインスタンスを作ってみましょう。
C#Person p1 = new Person("Taro", 20);
Person p2 = new Person("Hanako", 25);
Console.WriteLine($"{p1.Name}:{p1.Age}");
Console.WriteLine($"{p2.Name}:{p2.Age}");
実行結果は次のとおりです。
C#Taro:20
Hanako:25
p1とp2は同じPersonクラスから作られていますが、別々のインスタンスです。それぞれ独立した値を持っています。
8-4. nullのまま使ってエラーになる例
次のコードは、初心者がよく遭遇するエラーです。
C#Person person = null;
person.Name = "Taro";
このコードを実行すると、NullReferenceExceptionが発生します。
理由は、personがどのインスタンスも参照していないからです。つまり、Person型の変数はありますが、実体がありません。
8-5. エラーを修正して正しくインスタンス化する例
先ほどのエラーは、newでインスタンス化することで修正できます。
C#Person person = new Person();
person.Name = "Taro";
Console.WriteLine(person.Name);
また、コンストラクターを使う場合は次のように書けます。
C#Person person = new Person("Taro", 20);
Console.WriteLine(person.Name);
Console.WriteLine(person.Age);
C#でクラスのメンバーを使う前には、その変数が正しくインスタンス化されているかを確認することが大切です。
9. 初心者が混同しやすい関連用語
9-1. インスタンス化と初期化の違い
インスタンス化は、クラスからオブジェクトを作ることです。
C#Person person = new Person();
初期化は、作成したオブジェクトに初期値を設定することです。
C#person.Name = "Taro";
person.Age = 20;
インスタンス化と初期化は同時に行われることもあります。
C#Person person = new Person
{
Name = "Taro",
Age = 20
};
また、コンストラクターを使って初期化することもできます。
C#Person person = new Person("Taro", 20);
つまり、インスタンス化は「作ること」、初期化は「最初の状態を設定すること」です。
9-2. インスタンスとオブジェクトの違い
インスタンスは、特定のクラスから作られた実体を指します。
C#Person person = new Person();
このpersonは、Personクラスのインスタンスです。
オブジェクトは、プログラム上で扱われる実体を広く指す言葉です。C#では、インスタンスをオブジェクトと呼ぶことも多いため、実務ではほぼ同じ意味で使われる場面もあります。
初心者のうちは、「クラスからnewで作ったものがインスタンスであり、オブジェクトでもある」と理解しておけば問題ありません。
9-3. インスタンスメンバーとstaticメンバーの違い
インスタンスメンバーは、インスタンスごとに使うフィールド、プロパティ、メソッドです。
C#class Person
{
public string Name;
public void SayHello()
{
Console.WriteLine($"こんにちは、{Name}です");
}
}
使うときはインスタンス化します。
C#Person person = new Person();
person.Name = "Taro";
person.SayHello();
一方、staticメンバーはインスタンス化せずにクラス名から使います。
C#class Counter
{
public static int Count;
}
呼び出し方は次のとおりです。
C#Counter.Count = 10;
インスタンスごとに値を分けたい場合はインスタンスメンバー、全体で共有したい場合はstaticメンバーを使います。
9-4. 参照型と値型の違い
C#のクラスは参照型です。参照型では、変数にはオブジェクトへの参照が入ります。
C#Person p1 = new Person();
Person p2 = p1;
この場合、p1とp2は同じインスタンスを参照します。
一方、intやbool、構造体などは値型です。
C#int a = 10;
int b = a;
b = 20;
Console.WriteLine(a); // 10
Console.WriteLine(b); // 20
値型では、代入時に値がコピーされます。
インスタンス化を理解するには、クラスが参照型であることを押さえておくと、代入やnullの挙動が理解しやすくなります。
9-5. 生成・宣言・代入の違い
宣言は、変数を使えるように名前と型を定義することです。
C#Person person;
生成は、newでインスタンスを作ることです。
C#new Person();
代入は、作成したインスタンスへの参照を変数に入れることです。
C#person = new Person();
次の1行では、宣言、生成、代入をまとめて行っています。
C#Person person = new Person();
この違いを理解しておくと、C#のインスタンス化に関するエラーを読み解きやすくなります。
10. C#のインスタンス化でよくある質問
10-1. newしないとクラスは使えないのか
通常のクラスのインスタンスメンバーを使うには、基本的にnewでインスタンス化が必要です。
C#Person person = new Person();
person.Name = "Taro";
ただし、staticメンバーはnewしなくても使えます。
C#Math.Abs(-10);
また、ASP.NETのDIやUnityのように、フレームワークがインスタンス化を行う場合もあります。その場合、自分でnewを書かなくても、内部的にはインスタンスが作られています。
10-2. インスタンス化はいつ行うべきか
インスタンス化は、そのオブジェクトが必要になったタイミングで行います。
たとえば、ユーザー情報を扱いたいなら、ユーザー情報が必要な場面でUserクラスをインスタンス化します。
C#User user = new User("Taro", "taro@example.com");
ただし、不要なタイミングで大量にインスタンスを作ると、メモリ使用量が増えたり、コードが複雑になったりします。
必要なデータや処理を明確にしてからインスタンス化することが大切です。
10-3. newしたインスタンスはいつ消えるのか
C#でnewしたインスタンスは、不要になったタイミングでガベージコレクションの対象になります。
たとえば、どこからも参照されなくなったオブジェクトは、将来的にメモリから解放されます。
C#Person person = new Person();
person = null;
この場合、最初に作成されたPersonインスタンスを参照する変数がなくなれば、ガベージコレクションの対象になります。
ただし、すぐに削除されるとは限りません。C#では、メモリ管理の多くをガベージコレクターが自動で行います。
10-4. 何度もnewすると問題があるのか
newを何度も使うこと自体は問題ではありません。必要なオブジェクトを作るためにnewを使うのは自然なことです。
C#Person p1 = new Person();
Person p2 = new Person();
Person p3 = new Person();
ただし、不要なインスタンスを大量に作ると、メモリ使用量が増えたり、パフォーマンスに影響したりする可能性があります。
特に、ループ内で大量のオブジェクトを作成する場合は注意が必要です。
C#for (int i = 0; i < 1000000; i++)
{
Person person = new Person();
}
必要な範囲でインスタンスを作り、使い回せるものは適切に使い回すことが大切です。
10-5. インスタンス化とメモリ解放の関係は何か
インスタンス化すると、メモリ上にオブジェクトが作成されます。使われなくなったオブジェクトは、ガベージコレクションによって自動的に回収されます。
通常のクラスであれば、開発者が明示的にメモリを解放する必要はほとんどありません。
ただし、ファイル、データベース接続、ネットワーク接続など、外部リソースを扱うオブジェクトでは注意が必要です。このような場合は、Disposeやusingを使ってリソースを解放します。
C#using StreamReader reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
C#ではメモリ管理は自動化されていますが、外部リソースの解放は意識する必要があります。
まとめ
C#のインスタンス化とは、クラスから実際に使えるオブジェクトを作ることです。
基本構文は次の形です。
C#クラス名 変数名 = new クラス名();
たとえば、Personクラスをインスタンス化する場合は次のように書きます。
C#Person person = new Person();
newを使うと、メモリ上にインスタンスが作成され、コンストラクターが呼び出されます。その後、変数を通じてフィールド、プロパティ、メソッドにアクセスできるようになります。
C#のインスタンス化で特に重要なポイントは、次のとおりです。
通常のクラスは、基本的にnewでインスタンス化して使います。インスタンス化していない変数はnullの可能性があり、そのまま使うとNullReferenceExceptionが発生します。コンストラクターを使うと、インスタンス作成時に初期値を設定できます。abstractクラス、interface、staticクラスは直接インスタンス化できません。staticメンバーは、インスタンス化せずにクラス名から直接使います。
C#のインスタンス化は、オブジェクト指向プログラミングの基本です。最初はnewの意味がわかりにくく感じるかもしれませんが、「クラスは設計図」「インスタンス化は実体を作ること」と考えると理解しやすくなります。クラス、コンストラクター、参照型、nullの関係を押さえておくことで、C#のコードをより正確に読み書きできるようになります。

