2011-06-28 16 views
5

Üç sınıfım var, Base, Derived ve Final. Derived, Base ve Final'dan türetilen Derived'dan türetilmiştir. Her üç sınıfın da statik bir kurucusu vardır. Setup adlı genel bir statik yöntem olarak Sınıf Derived. Final.Setup numaralı telefonu aradığımda, üç statik kurucunun da çalışmasını beklerim, ancak yalnızca Derived numaralı telefondan yalnızca biri çalışır. Bu sadece kısmen banaNeden tüm statik yapıcılar C# (yani üst sınıflarınkiler) denir?

abstract class Base 
    { 
     static Base() 
     { 
      System.Console.WriteLine ("Base"); 
     } 
    } 

    abstract class Derived : Base 
    { 
     static Derived() 
     { 
      System.Console.WriteLine ("Derived"); 
     } 

     public static void Setup() 
     { 
      System.Console.WriteLine ("Setup"); 
     } 
    } 

    sealed class Final : Derived 
    { 
     static Final() 
     { 
      System.Console.WriteLine ("Final"); 
     } 
    } 

anlamda yapar: Burada

örnek kaynak kodudur. Final.Setup() numaralı telefonun aslında Derived.Setup() için bir takma ad olduğunu anlıyorum, bu nedenle Final'daki statik yapıcıyı atlamak yeterince iyi görünüyor. Ancak, neden Base statik kurucusu aranmıyor?

Bunu, Base no'lu bir işlem statik yöntemini arayarak veya Base kukla statik yöntemine erişerek giderebilirim. Ama merak ediyordum: Bu garip davranışların ardındaki mantık nedir?

+0

http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx – Cipi

+0

İlgili değil, bir çift: http://stackoverflow.com/questions/6390960/c- static-constructor-den-türetilmiş-sınıf- – Abel

cevap

5

statik yapıcı (TCPL) için uygun olarak adlandırılır:

  • sınıf türü bir örneği

    oluşturulur.
  • Sınıf türünün statik üyelerinden biri başvurulan. Statik yapıcı varsa, o ana yöntemi denir önce adı verilecek:

Bir örnek olarak, yürütme başlar edildiği statik Main yöntemi ile bir sınıf düşünün.

Statik kurucu çalıştırılmadan önce bile, herhangi bir statik alanın varsayılan değerlerine başlatıldığını ve daha sonra bu alan için statik alan başlatıcılarının çalıştırıldığını unutmayın. Ancak o zaman, statik kurucu (cctor) yürütülür. Statik kurucular miras alınmaz ve bunlar dolayısıyla sizin Base cctor senaryonuzdaki denilen olmayacak, doğrudan denilen, sen soyut Base sınıf statik bir yöntem vermedikçe ve olamaz:


daha doğrudan soruya cevap vermek için Önceden önerdiğiniz gibi, ilk önce, yani Base.Initialize() numaralı gibi arayın. akıl Hakkında

, o (Java bu farklıdır) C# düşünerek basit: statik yöntemler dolayısıyla devralınmamış bu istenmeyen yan etkilere neden olabilir gibi statik kurucular ne miras edilmelidir (adında bir cctor şey o sınıfı başvuruda bulunduğunda).

+0

Açıklamalarınız için teşekkür ederiz. Bu şimdi bana mantıklı geliyor. –

0

C# kuralları, sınıfın ilk örneği oluşturulmadan önce statik yapıcıların çağrıldığını veya herhangi bir statik öğeye dokunulduğunu, muhtemelen durumunuzda olduğu gibi ergo olmayacağını belirtir.

+0

@phresnel: Benim durumumda, hiçbir zaman hiçbir nesne yaratmam, sadece 'Derived.Setup()' yi çağırmak statik yapıcının 'Türetilmiş 'üzerinde çalışmasına neden olur. Öyleyse, statik kurucular yalnızca bir sınıfın oluşturulmasından önce çağrılmazlar. –

+0

@phresnel Tam olarak değil: "İlk örnek oluşturulmadan veya herhangi bir statik üyeye başvurulmadan önce sınıfı başlatmak için statik bir kurucu otomatik olarak çağrılır." Yorumdaki bağlantıdan. Bu, Base'deki herhangi bir şeye erişirse, statik yapıcısının ateşleneceği anlamına gelir. –

+0

@Pierre Sanırım yorumumu sorunuzu yanıtlıyor. Asla Base ile hiçbir şey yapmazsınız, bu yüzden yukarıdaki kuralla, statik yapıcısı ateş etmeyecektir. –

1

Statik yöntemler sınıfa aittir ve herhangi bir kalıtım yoktur. Final.Setup'u arayabilmeniz, sadece Derived.Setup'ı çağırmak için sözdizimsel bir şekerdir, bu nedenle Final'in hiçbir statik üyesi referans alınmamıştır - bu nedenle statik yapıcı aranmaz. Base sınıfı için aynı - Statik üyeler üzerinde herhangi bir kalıtım yoktur, bu nedenle Base sınıfı burada hiçbir şekilde yer almaz.

İlgili konular