PR

[C# 入門] クラスのインスタンスについて

今回はクラスのインスタンスについてです。
クラスについての記事にインスタンスというワードが出てきましたが、少しくわしく解説します。
ここはC#つまずきやすいところなので、なるべくわかりやすく説明したいと思います。

[C# 入門] クラス(class)について
クラス(class)とは クラスは値や変数、メソッドなどをひとまとまりにしたものです。とりあえずこれだけ覚えておきましょう。 もう少しちゃんと書くと、クラスはユーザー定義型と言って、開発者が変数やメソッドを自由に組み合わせて1つの新しいデー...
スポンサーリンク

インスタンスとは?

クラスについてで「クラスを使えるようにするには、newキーワードを使ってインスタンスを作成します。」と書きました。

クラスはユーザーが作る新しいデータ型です。
クラスの定義はパソコンに「こんなデータ型があります」と教えるためのものです。
実際にクラスを使うためにはパソコンに頼んでクラスを使える状態にしてもらいます。

頼まれたパソコンはメモリー上にクラスのフィールドを格納するための場所を作ったり、
メソッドがどんな引数が必要でどういう処理をするのかという情報を作成します。
作成された情報がそのクラスのインスタンスと呼ばれるものです。

インスタンスが作られるとパソコンはここに作ったという場所情報(アドレスと言ったりする)を返してきます。これを変数に入れるとクラスが使える状態になります。

//クラスの定義
class Sample
{
    public int X;
    public void Method() { }
}

class Program
{
    public static void Main()
    {
        //クラスのインスタンスを作成
        Sample a = new Sample();
    }
}

こんなイメージ、

[C#]インスタンスの作成

変数aはクラスのインスタンスを差し示しています。
この状態の変数aをクラスのオブジェクトと呼んだりします。
こんなイメージ、

[C#]クラスのオブジェクト

そもそもなんでこんなことが必要か?

値型と呼ばれるintboolなどは使用するバイト数が決まっているので、変数の宣言時にメモリー上に必要な分だけ領域が確保されます。

クラスは変数やメソッドを自由に組み合わせて使われるので、どのくらいの領域(バイト数)が必要なのかわかりません。なので「こんなデータとメソッドの組み合わせです」という情報(クラスの定義)をもとに領域を確保する必要があります。
こちらは、変数にインスタンスの場所が格納されるので参照型と呼ばれます。

というわけで、
参照型に分類される型はサイズがあらかじめ決まっていないのでインスタンスを作成する必要があります。参照型はクラスの他に配列やインターフェースなどがあります。

クラスインスタンスのメンバーへのアクセス

「変数a.フィールド名」とすると、クラスインスタンスのフィールドを指し示します。

[C#]インスタンス_フィールドへのアクセス
Sample a = new Sample();
a.X = 10;  //クラスのフィールドXに10を代入

「変数a.メソッド名」 とするとクラスインスタンスのメソッドを指し示します。

[C#]インスタンス_メソッドへのアクセス
Sample a = new Sample();
a.Method();  //クラスのメソッドを実行
スポンサーリンク

それぞれのインスタンス

インスタンスは new を実行するごとに新しく作成されます。
クラスのインスタンスを3つ作成してみます。

class Sample
{
    public int X;
    public void Method() { }
}

class Program
{
    public static void Main()
    {
        Sample a = new Sample();
        Sample b = new Sample();
        Sample c = new Sample();
    }
}

変数a、変数b、変数cはそれぞれ別のインスタンスを差し示しています。

[C#]別々のインスタンスを作成
スポンサーリンク

フィールドに値を設定してみる

2つ変数がそれぞれ別のインスタンスを指している場合と、
2つ変数が同じインスタンスを指している場合、違う動きをするため注意が必要です。

それぞれのインスタンスを指している場合

フィールドにint型の変数X、Yを持っているクラスを定義し、
2つのインタンスを作成し、それぞれのフィールドに値を設定してみます。

class Sample
{
    public int X;
    public int Y;
}

class Program
{
    public static void Main()
    {
        Sample a = new Sample();
        Sample b = new Sample();

        a.X = 10;
        a.Y = 20;

        b.X = 30;
        b.Y = 40;

        System.Console.WriteLine($"a.X = {a.X}, a.Y = {a.Y}");
        System.Console.WriteLine($"b.X = {b.X}, b.Y = {b.Y}");
    }
}

結果はこんな感じです。

a.X = 10, a.Y = 20
b.X = 30, b.Y = 40

11、12行目でそれぞれのインスタンスが作成され、変数a、bがそれらを差している状態になります。

[C#]インスタンスの参照先

14~18行目で、
それぞれが指しているインスタンスのフィールドにアクセスしてそれぞれ値が設定されます。

[C#]インスタンスの別々の参照先

同じインスタンスを指している場合

フィールドにint型の変数X、Yを持っているクラスを定義し、
2つの変数が同じインスタンスを指している状態でフィールドの値を設定してみます。

class Sample
{
    public int X;
    public int Y;
}

class Program
{
    public static void Main()
    {
        Sample a = new Sample();
        Sample b = a;  // 変数aの参照情報を変数bに代入

        a.X = 10;
        a.Y = 20;

        b.X = 30;
        b.Y = 40;

        System.Console.WriteLine($"a.X = {a.X}, a.Y = {a.Y}");
        System.Console.WriteLine($"b.X = {b.X}, b.Y = {b.Y}");
    }
}

結果はこんな感じです。

a.X = 30, a.Y = 40
b.X = 30, b.Y = 40

変数a、変数bのフィールドに同じ値が設定されています。
どういうことかというと、

11行目でSampleクラスのインスタンスを作成しています。
12行目で11行目で作成したインスタンスの参照情報をコピーしています。
こんな状態になります。

[C#]インスタンスの参照先(同じ場合)

14、15行目でインスタンスのフィールドXに10Yに20を設定しています。

[C#]インスタンスの参照先(同じ場合)2

17、18行目でインスタンスのフィールドXに30Yに40を設定しています。
変数bは変数aと同じインスタンスを指しているのでフィールドの値が上書きされます。

[C#]インスタンスの参照先(同じ場合)3
スポンサーリンク

インスタンスの寿命

基本的に、作成されたインスタンスはどこからも参照がなくなるとC#が自動で破棄(メモリーに確保した場所を解放して他のプログラムが使えるようにする)してくれます(ガベージコレクションという)。

.NET ガベージ コレクション
.NET のガベージ コレクションについて説明します。 .NET のガベージ コレクターは、アプリケーションのメモリの割り当てと解放を管理します。

「どこからも参照がなくなる」のはこんなとき、

  • スコープが外れたとき(くわしくはそのうち)
  • 他の値、nullが代入されて、どの変数にもそのインスタンスの参照情報が入っていないとき
  • プログラムが終了したとき

また、手動で破棄が必要なものはIDisposableインターフェースを実装しているのでusingを使って変数を宣言するようにします。くわしくはそのうちまとめる予定です。


C# 記事まとめページに戻る(他のサンプルコードもこちら)

C# プログラミング講座
C#についての記事まとめページです。開発環境VisualStudioのインストール方法や使い方、プログラミングの基礎知識についてや用語説明の記事一覧になっています。講座の記事にはすぐに実行できるようにサンプルコードを載せています。

コメント