C # 'da statik kurucu ne zaman çağrılır?


88

Statik bir oluşturucu içeren bir sınıfa sahip olduğumda, bu kurucu, sınıfı içeren derleme ilk yüklendiğinde veya bu sınıfa ilk başvuru vurulduğunda çağrılır mı?

Yanıtlar:


93

Sınıfa ilk kez erişildiğinde.

Statik Oluşturucular (C # Programlama Kılavuzu)

Statik bir yapıcı, herhangi bir statik veriyi başlatmak veya yalnızca bir kez gerçekleştirilmesi gereken belirli bir eylemi gerçekleştirmek için kullanılır. İlk örnek oluşturulmadan veya herhangi bir statik üyeye başvurulmadan önce otomatik olarak çağrılır.


6
"İlk örnek oluşturulmadan veya herhangi bir statik üyeye başvurulmadan önce" demesi ilginçtir. Aslında çağrıldığı zaman orada bir boşluk var .
Tim Barrass

6
@TimBarrass, diğer bazı şartname gereksinimleri nedeniyle "önce" nin aslında "hemen önce" olduğu ortaya çıkıyor - Jon
Skeet'in

A static constructor is used to initialize any static dataHAYIR. static initializerStatik şeyleri başlatmak için kullanmak daha iyidir.
Yousha Aleayoub

41

Basit belgelere rağmen beklediğiniz kadar basit değil. Jon Skeet'in http://csharpindepth.com/Articles/General/Beforefieldinit.aspx makalesi bu soruya ayrıntılı olarak giriyor.

Özet:

Statik oluşturucunun, o sınıfın bir üyesine yapılan ilk başvurudan hemen önce çalıştırılması garanti edilir - örneğin oluşturulması veya sınıfın kendi statik yöntemi / özelliği.

Statik başlatıcıların (statik kurucu yoksa) belirli bir alana ilk başvurmadan önce herhangi bir zamanda çalıştırılmasının garanti edildiğini unutmayın .


Bahsi geçen makale şu anda Jon Skeet'in
Mishra

Aşağıdaki stackoverflow.com/questions/32525628/… sorusunu takiben , "ani" davranışın oldukça açık olduğu durumu gösterir.
Alexei Levenkov

1
Aslında, bir konsol uygulamasının Main yöntemi çalışmaya başlamadan hemen önce statik bir kurucunun çağrıldığı bir durum vardı!
HerpDerpington

19

Statik kurucu, sınıfta herhangi bir şey kullanmadan önce çağrılır, ancak bunun tam olarak ne zaman olacağı uygulamaya bağlıdır.

İlk statik üyeye erişilmeden ve ilk örnek oluşturulmadan önce çağrılması garanti edilir. Sınıf hiçbir zaman kullanılmazsa, statik oluşturucunun çağrılması garanti edilmez.


2
O durumda değil "bir uygulama alanı içinde oluştuğu aşağıdaki olaylardan ilk tetiklediği statik yapıcı yürütülmesini: uygulanmasının ECMA C # spec takip ederse "uygulanmasına kadar"[1] bir örneği sınıf oluşturulur. [2] Sınıfın statik üyelerinden herhangi birine başvurulur. " (Bölüm 17.11, ecma-international.org/publications/standards/Ecma-334.htm )
LukeH

1
@Luke: "Statik yapıcı yürütmesinin tam zamanlaması uygulamaya bağlıdır" ondotnet.com/pub/a/dotnet/2003/07/07/staticxtor.html
Guffa

2
@Guffa: Bu, makale yazarının yorumu olabilir, ancak bu ifadeyi C # spesifikasyonunun Microsoft veya ECMA / ISO sürümlerinde bulamazsınız.
LukeH

1

Statik yöntemin üst sınıftan çağrılması durumunda, açıkça belirtilmesine rağmen statik yapıcı çağrılmayacaktır. Burada bir örnek b yapıcısı, b.methoda () çağrılırsa çağrılmaz.

static void Main(string[] args)
{
    b.methoda();
}

class a
{
    public static void methoda()
    {
        //using initialized method data
    }
}

class b : a
{
    static b()
    {
        //some initialization
    }
}    

1

Statik kurucularla ilgili başka bir yerde yanıtlanan ancak basit bir açıklamayı sindirmesi biraz zaman alan bir sorun var gibi görünüyor. Tüm belgeler ve açıklamalar, statik oluşturucu / başlatıcıların, birinci sınıf başlatılmadan veya ilk statik alana başvurulmadan önce çalışmasının "garantili" olduğunu iddia eder. Gotcha, sınıfa kendi örneğini (tavuk / yumurta) oluşturan statik bir singleton koymaya çalıştığınızda gelir. Bu durumda, statik oluşturucu, örnek oluşturucudan sonra çağrılır ve benim durumumda örnek oluşturucu, bazı statik verilere dayanan kod içeriyordu.

Statik yapıcı, örnek oluşturucudan sonra mı çağrıldı?

Statik yapıcı, statik olmayan yapıcıdan sonra çalışabilir. Bu bir derleyici hatası mı?

(benim için cevap, singleton'ı ayrı bir sınıfa koymak veya gerekli olmadan önce örnek oluşturucudaki statik verileri manuel olarak başlatmaktı)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.