web-dev-qa-db-ja.com

C#の静的コンストラクター

次のような静的コンストラクタを使用しようとしています:

public static DataManager()
{
    LastInfoID = 1;
}

このエラーが発生します:

アクセス修飾子は静的コンストラクタでは許可されていません

何が問題なのか知りたいのですが。

44
Nadav Stern

静的コンストラクタにはnoアクセス修飾子があります。

static DataManager() // note no "public"
{
    LastInfoID = 1;
}

これは明示的には呼び出されないためです(おそらくリフレクションを介して)-ランタイムによって呼び出されます。アクセスレベルは意味がありません。

101
Marc Gravell

問題は、LastInfoIDフィールドまたはプロパティがクラスで static として宣言されておらず、静的コンストラクターから静的メンバーのみにアクセスできることです。また、宣言からpublicキーワードを削除します。

static DataManager()
{
    LastInfoID = 1;
}
5
Darin Dimitrov

publicを削除します。静的コンストラクタの構文は次のとおりです。

class MyClass 
{
    static MyClass() 
    {
        // Static constructor
    }
}
5
Kirk Woll

ここにいる誰かに例を挙げずにより明確な答えを与えるには、なぜ外部から静的コンストラクタにアクセスする必要があるのか​​を考えてみてください。静的クラスは、アプリケーションの実行時にメモリ内に作成されるため、静的クラスです。つまり、明示的に呼び出す必要はありません。呼び出す場合、リフレクションを介して(それが許可されるかどうかはわかりませんが)言うと、何か間違っていることになります。

クラスの新しいインスタンスを作成するとき、コンストラクターはすべての内部変数を初期化し、クラスが意図したとおりに機能するために必要なあらゆる種類の処理を行う方法として存在します。コンストラクタを指定しない場合、コンパイラがコンストラクタを作成することに注意してください。このため、「()」を使用してクラスを作成する必要があります。

     new MyClass();

デフォルトのコンストラクターを呼び出しているため(パラメーターなしのコンストラクターが定義されていない場合)。つまり、非静的コンストラクターをパブリックとして定義する必要があるのは、明示的に呼び出す必要があるためです。メモリがうまく機能している場合、C#は、パブリックとして定義されていない(mallocを介して)コンストラクターを呼び出そうとするコードでコンパイルされません。

静的クラスのコンストラクターは、「セットアップ」の目的で存在します。たとえば、コードと、データの保存と読み取りを常に行っているファイルとの間の架け橋となる静的クラスを持つことができます。オブジェクトの作成時にファイルが存在することを確認し、作成されない場合はデフォルトのコンストラクタを作成するコンストラクタを定義できます(他のサーバーに移植されたWebシステムでは非常に役立ちます)。

5
Serguei Fedorov
using System;

public class Something
{
    //
    private static  DateTime _saticConstructorTime;
    private         DateTime _instanceConstructorTime;
    //
    public static DateTime SaticConstructorTime
    {
        set { _saticConstructorTime = value; }
        get { return _saticConstructorTime ; }
    }
    public DateTime InstanceConstructorTime
    {
        set { _instanceConstructorTime = value; }
        get { return _instanceConstructorTime; }
    }
    //Set value to static propriety 
    static Something()
    {
        SaticConstructorTime = DateTime.Now;
        Console.WriteLine("Static constructor has been executed at: {0}",
                        SaticConstructorTime.ToLongTimeString());
    }
    //The second constructor started alone at the next instances
    public Something(string s)
    {
        InstanceConstructorTime = DateTime.Now;
        Console.WriteLine("New instances: "+ s +"\n");
    }
    public void TimeDisplay(string s)
    {
        Console.WriteLine("Instance \""+ s + "\" has been created at: " + InstanceConstructorTime.ToLongTimeString());
        Console.WriteLine("Static constructor has been created at: " + SaticConstructorTime.ToLongTimeString() + "\n");
    }
}
//
class Client
{
    static void Main()
    {
        Something somethingA = new Something("somethingA");
        System.Threading.Thread.Sleep(2000);
        Something somethingB = new Something("somethingB");

        somethingA.TimeDisplay("somethingA");
        somethingB.TimeDisplay("somethingB");
        System.Console.ReadKey();
    }
}
/* output :

Static constructor has been executed at: 17:31:28
New instances: somethingA

New instances: somethingB

Instance "somethingA" has been created at: 17:31:28
Static constructor has been created at: 17:31:28

Instance "somethingB" has been created at: 17:31:30
Static constructor has been created at: 17:31:28
 */
1