静的クラスと静的クラス メンバ (C# プログラミング ガイド)
更新 : 2008 年 7 月
静的クラスは、基本的には非静的クラスと同じですが、静的クラスはインスタンス化できないという点が異なります。言い換えると、new キーワードを使用して、そのクラス型の変数を作成することはできません。インスタンス変数がないため、静的クラスのメンバにアクセスするには、クラス名そのものを使用します。たとえば、UtilityClass という静的クラスがあり、MethodA というパブリック メソッドが定義されている場合、このメソッドを呼び出すには次の例のようにします。
UtilityClass.MethodA();
すべてのクラス型と同様に、静的クラスの型情報は、.NET Framework の共通言語ランタイム (CLR: Common Language Runtime) によって、そのクラスを参照しているプログラムが読み込まれるときに読み込まれます。プログラムでは、クラスが読み込まれるタイミングを正確に指定することはできません。ただし、クラスがプログラム内で最初に参照される前に、そのクラスが読み込まれ、そのフィールドが初期化され、その静的コンストラクタが呼び出されることが保証されます。静的コンストラクタは一度だけ呼び出され、静的クラスは、プログラムが存在するアプリケーション ドメインの有効期間にわたってメモリに保持されます。
静的クラスは、入力パラメータに対してのみ処理を行い、内部のインスタンス フィールドを取得したり設定したりする必要のない一連のメソッドを格納する、便利なコンテナとして使用できます。たとえば、.NET Framework クラス ライブラリでは、静的クラス System.Math に、数値演算を実行するいくつかのメソッドが含まれています。これらのメソッドでは、Math クラスの特定のインスタンスに依存するデータを格納または取得する必要は生じません。
![]() |
---|
インスタンスの作成を 1 つしか許さない非静的クラスを作成する方法については、「C# でのシングルトンの実装」を参照してください。 |
静的クラスの主な特徴を次の一覧に示します。
静的メンバのみが含まれます。
インスタンス化できません。
シールされています。
インスタンス コンストラクタを含めることはできません。
したがって、静的クラスを作成することと、静的メンバとプライベート コンストラクタのみを含むクラスを作成することは、基本的に同じです。プライベート コンストラクタは、クラスのインスタンス化を防止します。静的クラスを使用する利点は、インスタンス メンバが誤って追加されないことをコンパイラで確認できるという点です。コンパイラによって、このクラスのインスタンスを作成できないことが保証されます。
静的クラスはシールされるため、継承できません。Object 以外のクラスから継承することはできません。静的クラスにインスタンス コンストラクタを含めることはできませんが、静的コンストラクタを含めることは可能です。特別な初期化を必要とする静的メンバがクラスに含まれている場合は、非静的クラスであっても静的コンストラクタを定義する必要があります。詳細については、「静的コンストラクタ (C# プログラミング ガイド)」を参照してください。
使用例
次に、摂氏と華氏の間で温度を変換する 2 つのメソッドを含む静的クラスのコード例を示します。
public static class TemperatureConverter
{
public static double CelsiusToFahrenheit(string temperatureCelsius)
{
// Convert argument to double for calculations.
double celsius = Double.Parse(temperatureCelsius);
// Convert Celsius to Fahrenheit.
double fahrenheit = (celsius * 9 / 5) + 32;
return fahrenheit;
}
public static double FahrenheitToCelsius(string temperatureFahrenheit)
{
// Convert argument to double for calculations.
double fahrenheit = Double.Parse(temperatureFahrenheit);
// Convert Fahrenheit to Celsius.
double celsius = (fahrenheit - 32) * 5 / 9;
return celsius;
}
}
class TestTemperatureConverter
{
static void Main()
{
Console.WriteLine("Please select the convertor direction");
Console.WriteLine("1. From Celsius to Fahrenheit.");
Console.WriteLine("2. From Fahrenheit to Celsius.");
Console.Write(":");
string selection = Console.ReadLine();
double F, C = 0;
switch (selection)
{
case "1":
Console.Write("Please enter the Celsius temperature: ");
F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine());
Console.WriteLine("Temperature in Fahrenheit: {0:F2}", F);
break;
case "2":
Console.Write("Please enter the Fahrenheit temperature: ");
C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine());
Console.WriteLine("Temperature in Celsius: {0:F2}", C);
break;
default:
Console.WriteLine("Please select a convertor.");
break;
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Example Output:
Please select the convertor direction
1. From Celsius to Fahrenheit.
2. From Fahrenheit to Celsius.
:2
Please enter the Fahrenheit temperature: 20
Temperature in Celsius: -6.67
Press any key to exit.
*/
静的メンバ
非静的クラスには、静的メソッド、フィールド、プロパティ、イベントを含めることができます。静的メンバは、クラスのインスタンスが作成されていない場合でもクラスで呼び出すことができます。静的メンバには、必ずインスタンス名ではなくクラス名でアクセスします。クラスのインスタンスがいくつ作成されていても、静的メンバのコピーは 1 つしか存在しません。静的メソッドと静的プロパティは、それを含んでいる型の非静的フィールドや非静的イベントにはアクセスできません。また、メソッド パラメータに明示的に渡されない限り、どのオブジェクトのインスタンス変数にもアクセスできません。
クラス全体を静的として宣言するよりも、非静的クラスを宣言して、いくつかの静的メンバを含める方が一般的です。静的フィールドの一般的な用途として、インスタンス化されたオブジェクトの数を保持することと、すべてのインスタンスで共有する必要のある値を格納することの 2 つがあります。
静的メソッドのオーバーロードはできますが、オーバーライドはできません。これは、静的メソッドがクラスのインスタンスではなくクラスに属しているためです。
フィールドを static const として宣言することはできませんが、const フィールドは、その動作において本質的に静的です。const フィールドは、型のインスタンスではなく型に属します。そのため、const フィールドにアクセスするには、静的フィールドに対して使用するのと同じ ClassName.MemberName 表記法を使用します。オブジェクト インスタンスは必要ありません。
C# では、静的なローカル変数 (メソッドのスコープで宣言された変数) はサポートされません。
静的クラスのメンバを宣言するには、次の例に示すように、メンバの戻り値の型の前で static キーワードを使用します。
public class Automobile
{
public static int NumberOfWheels = 4;
public static int SizeOfGasTank
{
get
{
return 15;
}
}
public static void Drive() { }
public static event EventType RunOutOfGas;
// Other non-static fields and properties...
}
静的メンバは初めてアクセスされる前に初期化されます。また、静的コンストラクタがある場合は、それが呼び出される前に初期化されます。静的クラスのメンバにアクセスするには、次の例に示すように、変数名の代わりにクラス名を使用してメンバの位置を指定します。
Automobile.Drive();
int i = Automobile.NumberOfWheels;
クラスに静的フィールドが含まれている場合は、クラスが読み込まれたときに静的フィールドを初期化する静的コンストラクタを用意します。
静的メソッドの呼び出しでは、Microsoft Intermediate Language (MSIL) の call 命令が生成されます。これに対して、インスタンス メソッドの呼び出しでは callvirt 命令が生成され、null オブジェクト参照もチェックされます。ただし、ほとんどの場合、2 つの間にパフォーマンス上の違いはそれほどありません。
C# 言語仕様
詳細については、「C# 言語仕様」の次のセクションを参照してください。
- 10.1.1.3 静的クラス
参照
概念
参照
インスタンス コンストラクタ (C# プログラミング ガイド)
履歴の変更
日付 |
履歴 |
理由 |
---|---|---|
2008 年 7 月 |
コンテンツとコード例を追加 |
情報の拡充 |