次の方法で共有


静的クラスと静的クラス メンバー (C# プログラミング ガイド)

静的クラスは基本的に非静的クラスと同じですが、1 つの違いがあります。静的クラスをインスタンス化することはできません。 つまり、 新しい 演算子を使用してクラス型の変数を作成することはできません。 インスタンス変数がないため、クラス名自体を使用して静的クラスのメンバーにアクセスします。 たとえば、UtilityClassという名前のパブリック静的メソッドを持つMethodAという名前の静的クラスがある場合は、次の例に示すようにメソッドを呼び出します。

UtilityClass.MethodA();

静的クラスは、入力パラメーターを操作するだけで、内部インスタンス フィールドを取得または設定する必要がない一連のメソッドの便利なコンテナーとして使用できます。 たとえば、.NET クラス ライブラリでは、静的 System.Math クラスには、 Math クラスの特定のインスタンスに固有のデータを格納または取得する必要なく、数学演算を実行するメソッドが含まれています。 つまり、次の例に示すように、クラス名とメソッド名を指定して、クラスのメンバーを適用します。

double dub = -3.14;
Console.WriteLine(Math.Abs(dub));
Console.WriteLine(Math.Floor(dub));
Console.WriteLine(Math.Round(Math.Abs(dub)));

// Output:
// 3.14
// -4
// 3

すべてのクラス型の場合と同様に、.NET ランタイムは、クラスを参照するプログラムが読み込まれるときに静的クラスの型情報を読み込みます。 プログラムでは、クラスが読み込まれるときに正確に指定することはできません。 ただし、クラスがプログラムで初めて参照される前に、フィールドを読み込んで初期化し、静的コンストラクターを呼び出す必要があります。 静的コンストラクターは 1 回だけ呼び出され、静的クラスは、プログラムが存在するアプリケーション ドメインの有効期間中、メモリ内に残ります。

それ自体のインスタンスを 1 つだけ作成できる非静的クラスを作成するには、「 C# でのシングルトンの実装」を参照してください。

静的クラスの主な機能を次に示します。

したがって、静的クラスの作成は、静的メンバーとプライベート コンストラクターのみを含むクラスの作成と基本的に同じです。 プライベート コンストラクターは、クラスがインスタンス化されないようにします。 静的クラスを使用する利点は、インスタンス メンバーが誤って追加されていないことをコンパイラが確認できることです。 コンパイラは、このクラスのインスタンスを作成できないことを保証します。

静的クラスはシールされているため、継承できません。 Object以外のクラスまたはインターフェイスから継承することはできません。 静的クラスにインスタンス コンストラクターを含めることはできません。 ただし、静的コンストラクターを含めることができます。 非静的クラスは、クラスに単純でない初期化を必要とする静的メンバーが含まれている場合も静的コンストラクターを定義する必要があります。 詳細については、「静的コンストラクター」を参照してください。

温度を摂氏から華氏に、華氏から華氏に変換する 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() ?? "0");
                Console.WriteLine($"Temperature in Fahrenheit: {F:F2}");
                break;

            case "2":
                Console.Write("Please enter the Fahrenheit temperature: ");
                C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine() ?? "0");
                Console.WriteLine($"Temperature in Celsius: {C:F2}");
                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 フィールドには、静的フィールドに使用されるのと同じ 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;

クラスに静的フィールドが含まれている場合は、クラスの読み込み時にそれらを初期化する静的コンストラクターを指定します。

静的メソッドの呼び出しでは共通中間言語 (CIL) の呼び出し命令が生成されますが、インスタンス メソッドの呼び出しでは callvirt 命令が生成され、null オブジェクト参照もチェックされます。 ただし、ほとんどの場合、2 つのパフォーマンスの違いは重要ではありません。

C# 言語仕様

詳細については、C# 言語仕様静的クラス静的およびインスタンス メンバーおよび静的コンストラクターを参照してください。 言語仕様は、C# の構文と使用法の決定的なソースです。

こちらも参照ください