ここではC#のstaticについて学びます。
static
staticは静的クラスや静的メンバを作成する時に利用します。
ここではC#のクラスについて学びます。クラスはC#において最も大切な機能だと思ってます。それもあって最低限の内容を書いたつもりが、何かめっちゃ長くなりました。疲れたら数回に分けて読んでください。クラス(class)クラスとは特定の機能を1つにまとめたものです。正直、説明が難しいのでコードを使って話します。最初に以下の記述方法とサンプルコードを見てください。これは車という機能をクラス化したコードです。// クラス public class Car { ...
実はサンプルで既に利用していて、Main関数がstatic宣言されてます。
static void Main(string[] args)
では、このstaticは何を意味するのでしょうか?
静的とは「動かない」とか「一定」と言う意味らしいです。
より簡単に言うと、staticを付けたクラスやメソッドはアプリケーションで1つだけの存在(共通利用)になります。
以前にクラスは設計図、インスタンスを生成しないと使えないと言いましたが、staticを付けるとインスタンスを生成しなくても使えます。
だからインスタンスを生成しなくてもMain関数は動いてたんですね。
そうだよ。
その代わり共通利用されるので、全ての処理で同じクラスやメソッドが呼び出されます。
特に分かりやすいのがフィールドでしょう。試しに以下のサンプルコードを実行してください。
namespace Sample
{
public class Counter
{
private static int count = 0; // staticフィールド
public void Up()
{
count++;
}
public void Display()
{
System.Console.WriteLine(count);
}
}
internal class Program
{
static void Main(string[] args)
{
var c1 = new Counter();
var c2 = new Counter();
c1.Display();
c2.Display();
c1.Up();
c1.Display();
c2.Display();
}
}
}
このようにstaticを付けたcount(フィールド)は複数のインスタンスから共通利用されます。
これが単なる非staticフィールドであれば、UP()メソッドが作用するのは自身のインスタンスのみです。
しかし、staticを付けたことでアプリケーションで唯一の存在になり、値が共通化されました。
staticを付ける対象で微妙に動作は異なりますが、根本はアプリケーションで1つの存在になることです。
仮にメソッドやプロパティに付ければ、インスタンスを生成しなくても呼び出せる機能を作れます。
アクセス方法
.(ドット)演算子を利用する部分は同じですが、インスタンスを生成しないため通常のアクセス方法とは微妙に異なります。
これは例を見たほうが分かりやすいと思います。先に以下のサンプルコードを実行してください。
namespace Sample
{
public class Display
{
public static void Output()
{
System.Console.WriteLine("りさ");
}
}
internal class Program
{
static void Main(string[] args)
{
Display.Output(); // staticメソッドにアクセス
}
}
}
こんな感じにインスタンス名ではなくクラス名を利用してアクセスします。
部分的に抜き出すと以下ですね。クラス名.メソッドって感じです。
Display.Output();
実は何度も登場してるSystem.Console.WriteLine()も同様の仕組みです。
これはSystem名前空間に存在するConsoleクラスのWriteLineメソッドにアクセスしてます。
static class
少し特殊なのがクラス自体にstaticを付ける場合です。
メソッドやフィールドであれば、それ単体が唯一の存在になりましたが、クラスに付けるとクラスの全てがstaticになります。
ただし、その代わり恐ろしく厳しい制約が付くので、安易に付けると設計不能になって色々と崩壊します。
先に課せられる制約は以下です。
- staticメンバ(メソッドやフィールド等)しか実装できない
- インスタンスが生成できない
- 継承できない(シール化される)
まだ、知らない単語もありますが、この中でも継承できないが最も厳しい制約です。
C#にはポリモーフィズムと呼ばれる神みたいな機能があって、それを担うのが継承の仕組みです。
ここではC#の継承について学びます。これはクラスの延長線の話になりますが少し難しいです。まずはクラスの基礎知識が必要なので、忘れてしまった人は以下で復習しましょう。継承(inheritance)継承とは、あるクラスを元に新しいクラスを定義することです。こうすることで新しく定義したクラスは元になったクラスの全ての機能を有することができます。簡単に言えば親子関係です。親(A)を元に子(B)を定義することができます。人間なら全ての特性を引き継ぐことはありませんが、この世...
がっ、staticを付けたクラスは継承自体ができなくなるので、その仕組みに乗りません。
C#は継承を利用して最高の設計ができる言語なんですが、それを真っ向から否定されてる感じがします。
過去にどんな罪を犯せばこんな制約が付くのか、まるで重罪人だよ。
それでも利用されてるってことは必要な機能なんですよね?
理解して使うなら便利だよ。まぁ、僕はstaticクラスは殆ど使わないけど。
static コンストラクタ
staticクラスはインスタンスが生成できない都合でコンストラクタが使えません。
その代わりに利用できるのがstaticコンストラクタです。これは名前の通りでstaticクラス用のコンストラクタです。
まずはサンプルコードで動作を確認しましょう。
namespace Sample
{
public class Display
{
private static string name;
// static コンストラクタ
static Display()
{
name = "りさ";
}
public static void Output()
{
System.Console.WriteLine(name);
}
}
internal class Program
{
static void Main(string[] args)
{
Display.Output();
}
}
}
staticが付いてるので、このコンストラクタにも制約があります。
具体的には以下なんですが、結論として1種類の記述しかできません。
- アクセス修飾子を記述できない
- 引数を付けることはできない
その結果、こんな感じの記述のみに対応します。
static クラス名()
{
}
また、普通のコンストラクタはインスタンス化したタイミングで呼び出されますが、そもそもstaticクラスはインスタンス化できません。
それもあり、staticコンストラクタは初めてstatic関連のメンバにアクセスした時、自動的に呼び出される仕様になってます。
つまりstaticメンバにアクセスする場合、事前にstaticコンストラクタが呼び出されることは必ず保証されます。
static利用時の注意
これは注意というより当然の結果なんですが、staticメンバはstaticなメンバにしかアクセスできません。
例えばstaticメソッドがあったとして、そのメソッドでインスタンスが所有する通常のフィールドにはアクセスできません。
これはstaticメソッドがインスタンス化を必要としない特性から、staticメソッドの利用時にインスタンスの存在が保証できないからです。
この様に絶対の確約がない情報は全てビルドエラーとして扱われます。これに関しては冷静にパターンを考えれば分かるので、ここでの説明は省きます。
あとがき
staticを利用する判断は経験を積まないと分からないと思います。特にstaticクラスなんかは余程の理由がなければ使いません。
C#はオブジェクト指向と呼ばれるインスタンスを利用する手法が基本です。なので、迷うくらいなら使わないほうがいいです。
◆ C#に関する学習コンテンツ
この記事は参考になりましたか?
コメント