static に関する注意

Copyright © 2003, Hirofumi Fujii
(LastUpdate: 03-Aug-2003)

C# に限った話ではないが、class 宣言内で宣言された static の扱いは 注意を要する。これは、「その class の object 間で共有される」という意味で ある。別の言い方をすれば、「class に置かれ、object の外に存在する」という 意味である。従って、object が生成されていなくても存在し、 クラス名経由でアクセスすることができる。また、どれか一つの object が値を 書き換えると、他の object も影響を受けるということである。

例を示そう。以下のような class を考える。

public class Stc
{
  public static int a = 1;
  public int b = 2;

  public void SetA(int n) { a = n; return; }
  public int GetA() { return a; }

  public void SetB(int n) { b = n; return; }
  public int GetB() { return b; }

}
この class で使われている変数 a と b の違いは、static であるかどうか である。このクラスに対し、次のようなテストプログラムを書いてみる。
public class StcTest
{
  public static void Main()
  {
    System.Console.WriteLine( "Stc.a = " + Stc.a );
    Stc s1 = new Stc();
    System.Console.WriteLine( "[1]: a = " + s1.GetA() + ", b = " + s1.GetB() );
    s1.SetA( 6 );
    s1.SetB( 7 );
    System.Console.WriteLine( "[1]: a = " + s1.GetA() + ", b = " + s1.GetB() );
    Stc s2 = new Stc();
    System.Console.WriteLine( "[2]: a = " + s2.GetA() + ", b = " + s2.GetB() );
  }
}

最初に、object を生成せずにクラス名 Stc を使って変数 a にアクセスしている。 a は static であるので、このような芸当ができる。

object s1 を生成後、a と b の値を SetA() と SetB() を通じて書き換えてから、 object s2 を生成している。

このプログラムの実行結果を示そう。

C:\My Documents\dotnet>sttest
Stc.a = 1
[1]: a = 1, b = 2
[1]: a = 6, b = 7
[2]: a = 6, b = 2

C:\My Documents\dotnet>

a は static 変数であるので、その書き換えの影響が s2 に出ている。一方 b は object 内の変数であるので、s1 の設定にかかわらず、初期値が設定されている ことがわかる。