2009-03-04 25 views

cevap

108

Bu konuyla ilgili olarak my article adresine bakın.

Temel olarak, beforefieldinit "tür, herhangi bir statik alan referans alınmadan önce herhangi bir noktada başlatılabilir." teorisinde çok tembel başlatılmış olabilir - herhangi bir alana dokunmayan statik bir yöntem çağırırsanız, JIT türünü başlatmaya gerek duymaz. Uygulamada yılında

buna başka türlü olurdu sınıf öncekivar demektir - bu kullanabilecek ilk yöntemin başlangıcında başlatılması için önemli değil. Bunu, 'un'un beforefieldinit'a uygulanmadığı türlerle karşılaştırın; burada tür başlatımı, ilk gerçek kullanımdan hemen önce gerçekleşmelidir.

Yani, biz varsayalım:

public static void DoSomething(bool which) 
{ 
    if (which) 
    { 
     FirstType.Foo(); 
    } 
    else 
    { 
     SecondType.Bar(); 
    } 
} 

her iki tür (tip statik yapıcı olmadıkça C#, varsayılan olarak yapmak) uygulanmış beforefieldinit varsa o zaman hem başlatıldı olacak Yöntemin başında (genellikle - garanti edilmez). Eğer beforefieldinit yoksa, bunlardan sadece bir bayrağına göre başlatılacaktır.

Bu nedenle, implementing the singleton pattern olduğunda statik bir kurucu (boş bir kişi!) Kullanmak yaygındır.

+0

içinde değişecek gibi görünüyor "Herhangi alanlar başvurulan önce tip herhangi bir noktada başlatılabilir." _ Statik yöntemler çalıştırmak için doğrudur da nedir? –

+0

@RoyiNamir, CLI özellikleri, BeforeFieldInit uygulandığında, "türün başlatıcı yöntemi, bu tür için tanımlanan herhangi bir statik alana ilk önce veya daha önce yürütülür", diyor. Bu öznitelik atlanırsa (statik .ctor) o zaman "bu türdeki herhangi bir statik veya örnek alanına ilk erişim veya bu türdeki herhangi bir statik, örnek veya sanal yöntemin ilk çağrılması". Bu nedenle, statik yöntem başka bir statik alana başvurmadıkça, BeforeFieldInit için geçerli değildir. –

+2

Statik kurucuların kullanılmasına yönelik bir performans cezası olduğunu fark ettim (yani, önceden konumlandırılmış bayrağı bulunmayan sınıflar). Belirli bir sınıfa ait statik üyeleri sık sık çağırırsanız, çalışma zamanının, türün henüz başlatılmamış olup olmadığını sınamak için her aramadan önce ek bir kontrol yapması gerektiği görülür; Bu kontrollerden kaçınır. Birkaç kıyaslama daha önce% 50 daha hızlıydı: http://www.codeproject.com/Articles/87991/Dynamic-interfaces-in-any-NET-language – Qwertie

4
+0

Awesome, bu kadar bekleyeceğiniz anlamına geliyor alanı sonlandırmak için son anı (eğer 'önceden planlanmış olup olmadığına bakılmaksızın)? –

+1

İlk kullanımdan önce tüm girişler başlangıç ​​kontrolü ile öneklenecektir. Bundan sonra, diğer yöntemler jatch edildiğinde, oluşturulan kod doğrudan alana erişecektir. Eğer ilkel bir tipse, JIT zaman sabiti olarak da kullanılabilir. – OmariO

+0

Jon'un başlatma başlatma türündeki değişikliklerle ilgili ayrıntılı analizi .Net 4.0 [burada] (https: //codeblog.jonskeet.uk/2010/01/26/tip-başlatma-değişimler-in-net-4-0 /). – RBT