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 の設定にかかわらず、初期値が設定されている ことがわかる。