C# フィールド変数とブロックスコープの学習資料

C# のプログラムをしっかり理解するには、フィールド変数のスコープだけでなく、ブロックスコープについても学ぶ必要があります。
この資料では、フィールド変数のスコープブロックスコープの違いを解説し、具体例と練習問題を用意しました。


1. スコープとは?

スコープとは、変数が有効な範囲(アクセスできる範囲)のことです。
C# では、変数のスコープには大きく以下の4種類があります。

種類スコープ(有効範囲)
フィールドスコープクラスのすべてのメソッド内で有効
メソッドスコープメソッド内でのみ有効
ブロックスコープ{} で囲まれたブロック内でのみ有効
静的(static)スコープクラス全体で1つの値を保持し、インスタンス間で共通

2. フィールド変数のスコープ

フィールド変数(メンバ変数)は、クラス内のすべてのメソッドでアクセス可能ですが、アクセス修飾子によって制限できます。

サンプルコード

using System;

class Person
{
    // フィールド変数(クラス内のどこでもアクセス可能)
    private string name;
    public int age;

    public void SetName(string newName)
    {
        name = newName; // フィールド変数を変更
    }

    public void ShowInfo()
    {
        Console.WriteLine($"名前: {name}, 年齢: {age}");
    }
}

class Program
{
    static void Main()
    {
        Person p = new Person();
        p.age = 30;
        p.SetName("太郎");
        p.ShowInfo();  // 名前: 太郎, 年齢: 30
    }
}

ポイント

nameprivate なので Program から直接アクセス不可。
SetName() を使って name を変更できる。
agepublic なので、Program から直接アクセス可能。


3. ブロックスコープとは?

ブロックスコープとは、{} で囲まれた範囲内でのみ有効な変数のスコープです。
ループや条件分岐、メソッド内部の {} で定義された変数は、そのブロック内でのみ使えます。

サンプルコード

using System;

class Program
{
    static void Main()
    {
        int x = 10;

        {
            int y = 20;
            Console.WriteLine(x); // OK(外のスコープの変数は使える)
            Console.WriteLine(y); // OK
        }

        // Console.WriteLine(y); // エラー(y はブロック外なので使えない)
    }
}

ポイント

y{} 内で定義されたので、その外では使えない。
xMain() の中で定義されたので、ブロックの内外で使える。


4. for ループのスコープ

for ループ内で定義された変数は、そのループの中でのみ有効です。

サンプルコード

using System;

class Program
{
    static void Main()
    {
        for (int i = 0; i < 3; i++)
        {
            Console.WriteLine(i);
        }

        // Console.WriteLine(i); // エラー(i は for ループのブロック内だけで有効)
    }
}

ポイント

ifor ループの {} 内でしか使えない。
i をループの外でも使いたい場合は、外で宣言する必要がある。

外で使いたい場合の修正

using System;

class Program
{
    static void Main()
    {
        int i; // ループの外で宣言
        for (i = 0; i < 3; i++)
        {
            Console.WriteLine(i);
        }
        Console.WriteLine($"ループの後の i: {i}"); // OK
    }
}

i をループの外で宣言すると、ループ後も使用可能になる。


5. ifwhile でのブロックスコープ

if 文や while 文の {} で定義された変数は、その中でのみ使えます。

サンプルコード

using System;

class Program
{
    static void Main()
    {
        if (true)
        {
            int num = 100;
            Console.WriteLine(num); // OK
        }
        // Console.WriteLine(num); // エラー(num は if のブロック内のみ有効)
    }
}

numif 文の {} 内でのみ使える。


6. フィールド変数とブロックスコープの違い

スコープ有効範囲特徴
フィールド変数クラス全体クラスのすべてのメソッドからアクセス可能
ローカル変数(メソッドスコープ)メソッド内メソッドが終了すると消える
ブロックスコープ{} 内のみ{} の外では使えない
static 変数クラス全体インスタンス間で共通の値を持つ

7. 練習問題

Q1. 次のコードの出力を予想してください

using System;

class Sample
{
    int num = 10;

    void Show()
    {
        int num = 20;
        Console.WriteLine(num);
    }

    static void Main()
    {
        Sample s = new Sample();
        s.Show();
    }
}
  1. 10
  2. 20
  3. エラーになる
  4. コンパイルできない

Q2. for ループの後に i を使うとエラーになるのはなぜ?

  1. istatic 変数ではないから
  2. ifor ループのブロックスコープ内にあるから
  3. ireadonly だから
  4. for の外に i が宣言されていないから

Q3. 次のコードはエラーになりますか?

using System;

class Program
{
    static void Main()
    {
        {
            int x = 10;
        }
        Console.WriteLine(x);
    }
}
  1. 10 が表示される
  2. エラーになる
  3. 何も表示されない
  4. プログラムが停止する

8. まとめ

フィールド変数 → クラス全体でアクセス可能
ローカル変数 → メソッド内でのみ有効
ブロックスコープ{} 内でのみ有効
static 変数 → クラス全体で1つの値を共有

これで、フィールド変数とブロックスコープをしっかり理解できます!


7. 練習問題(模範解答&解説付き)


Q1. 次のコードの出力を予想してください

using System;

class Sample
{
    int num = 10;

    void Show()
    {
        int num = 20;
        Console.WriteLine(num);
    }

    static void Main()
    {
        Sample s = new Sample();
        s.Show();
    }
}

正解: 2. 20

解説

  • numSample クラスのフィールド変数(インスタンス変数)として 10 で初期化されている。
  • Show() メソッド内の num は、ローカル変数として宣言されており、20 に設定されている。
  • ローカル変数のスコープは、メソッド内に限定されるため、メソッド内の num が優先される。

したがって、Show() を実行すると 20 が表示される。


Q2. for ループの後に i を使うとエラーになるのはなぜ?

using System;

class Program
{
    static void Main()
    {
        for (int i = 0; i < 3; i++)
        {
            Console.WriteLine(i);
        }
        Console.WriteLine(i); // ここでエラー
    }
}

正解: 2. ifor ループのブロックスコープ内にあるから

解説

  • i のスコープは for ループの {} に限定される。
  • したがって、ループが終了した後には i は無効になり、エラーが発生する。
  • 修正方法: ifor の外で宣言する。
using System;

class Program
{
    static void Main()
    {
        int i; // ループの外で宣言
        for (i = 0; i < 3; i++)
        {
            Console.WriteLine(i);
        }
        Console.WriteLine($"ループの後の i: {i}"); // OK
    }
}

この修正により、ifor ループの外でも有効になり、エラーが解消される。


Q3. 次のコードはエラーになりますか?

using System;

class Program
{
    static void Main()
    {
        {
            int x = 10;
        }
        Console.WriteLine(x);
    }
}

正解: 2. エラーになる

解説

  • 変数 x{} 内で宣言されており、ブロックスコープが適用される。
  • ブロック {} を抜けると x は無効になり、Console.WriteLine(x); でエラーが発生する。
  • 修正方法: x をブロックの外で宣言する。
using System;

class Program
{
    static void Main()
    {
        int x; // ブロックの外で宣言
        {
            x = 10; // ブロック内で代入
        }
        Console.WriteLine(x); // OK
    }
}

この修正により、xMain() 内のどこでも使えるようになり、エラーが解消される。


C#,変数

Posted by hidepon