SORU
13 HAZİRAN 2015, CUMARTESİ


Neden yerel değişkenleri başlatma, ama alanlar bunu gerektirmez mi?

Eğer benim sınıf içinde bir bool oluşturmak, bool check, böyle bir şey yanlış olur.

Benim yöntem içinde aynı bool oluşturduğumda, bool check(yerine sınıf içinde), ben bir hata alıyorum "atanmamış yerel değişken kullanın" kontrol edin. Neden?

CEVAP
13 HAZİRAN 2015, CUMARTESİ


Yuval ve David'in cevaplar temelde doğru; özetle;

  • Atanmamış yerel bir değişken kullanımı büyük olasılıkla bir hata olduğunu ve bu düşük maliyetle derleyici tarafından tespit edilebilir.
  • Atanmamış bir alan ya da bir dizi öğe kullanımı daha az olasılıkla bir hata var ve derleyici bu durumu tespit etmek zordur. Bu nedenle derleyici alanlar için başlatılmamış bir değişken kullanımını tespit etmek için hiçbir girişimde bulunmaz, onun yerine program davranışı deterministik hale getirmek için varsayılan değer başlatma dayanır.

David'in cevap için bir yorumcu imkansız atanmamış bir alan kullanımını tespit etmek için neden statik analizi ile sorar; bunun üzerine bu cevabı genişletmek istiyorum noktasıdır.

Öncelikle, herhangi bir değişken veya başka yerel için, pratikte imkansız belirlemek içintam olarakister bir değişkene atanmış ya da atanmamış. Düşünün:

bool x;
if (M()) x = true;
Console.WriteLine(x);

"X atanır?" eşittir "M (true)?" return soru Şimdi, diyelim M() dönerse Fermat'nın Son Teoremi tüm tamsayılar sana onlarca zilyon daha az, aksi takdirde false değeri true ise true. X kesinlikle atanmış olup olmadığını tespit etmek amacıyla, derleyici aslında Fermat'ın Son Teoremi kanıtı üretmek gerekir. Derleyici o kadar akıllı biri değil.

Yani derleyici yerli yerine ne uygulayan bir algoritmahızlıveabarttıbir yerel kesinlikle atanır. Yani, "bu yerel atanmış ve ben bunu bilmeme rağmen". olduğunu kanıtlayamam diyor bazı yanlış pozitif vardır, Örneğin:

bool x;
if (N() * 0 == 0) x = true;
Console.WriteLine(x);

N() sanırım bir tamsayı döndürür. Sen ve ben, N() * 0 0, ama derleyici bilmez. (Not:# 2.0 C derleyiciyaptıama belirtim yok gibi optimizasyon kaldırıldıdemekderleyici biliyor.)

Tamam, biz şu ana kadar ne biliyoruz? Bu pratik için yerliler için kesin bir cevap, ama biz abartma değil-atanan-lik ve ucuza almak çok iyi bir sonuç bu hataları yanında "olun size tamir belirsiz program". Bu iyi bir şey. Neden alanları için aynı şey değil mi? Bu, ucuza abarttı kesin atama denetleyicisi olun.

Peki, başka nasıl bir yerel için başlatılmış. Yöntemi metin içinde atanabilir. Bu yöntem metni bir lambda içinde atanabilir; lambda asla çağrılan olabilir, bu atamalar ilgili değildir. Ya da "" hangi noktada yöntem normalde döndüğünde atanmış olduğunu kabul edebiliriz anothe yöntemi. out olarak geçiyor olabilir Bu, yerel atanır çok açık noktaları vardır, ve onlardoğru yerel aynı yöntemi ilan var. Yerliler için kesin atama belirlenmesi gerekiryerel analizi. Yöntem kısa bir yöntemi kodu, bir milyondan çok daha az hatları -- -- olma eğilimindedir ve bu yüzden tüm analiz yöntemi oldukça hızlı.

Şimdi alanlar ne olacak? Alanlar elbette bir kurucu olarak başlatılabilir. Ya alan bir başlatıcı. Veya oluşturucu alanları başlatır örnek bir yöntemini çağırabilir. Ya da yapıcı bir çağrısanalbu initailizes alanları yöntemi. Ya da yapıcı bir yöntemini çağırabilirbaşka bir sınıftaolabilir ., ^em>bir kütüphanedebu alanlar başlatır. Statik alanlar statik kurucular başlatılabilir. Statik alanlar tarafından başlatıldı olabilirdiğerstatik kurucular.

Aslında bir alan için başlatıcı olabilirher yerde tüm programıiçeride de dahil olmak üzereyazılmamış kütüphanelerdeki ilan edilecek sanal yöntemleri henüz:

// Library written by BarCorp
public abstract class Bar
{
    // Derived class is responsible for initializing x.
    protected int x;
    protected abstract void InitializeX(); 
    public void M() 
    { 
       InitializeX();
       Console.WriteLine(x); 
    }
}

Bu kütüphaneyi derlemek için bir hata mıdır? Evet ise, nasıl BarCorp hatayı düzeltecek mi? X için varsayılan değer mi? atayarak Ama bu derleyici zaten yapıyor.

Bu kütüphane yasal olduğunu varsayalım. FooCorp yazıyor

public class Foo : Bar
{
    protected override void InitializeX() { } 
}

bubir hata mı?Nasıl derleyici bunu anlamak gerekiyor?Tek yolu yapmaktırbütün program analizibu başlatma statik izlerher alanprogram aracılığıyla mümkün olan her yoludahil , bu yolları da dahil olmak üzerezamanında sanal yöntemlerin seçimi. Bu sorun olabilirsabit keyfi; denetim milyonlarca simüle yürütme dahil olabilir yolları. Analiz yerel denetim akışları mikrosaniye alır ve Yöntem boyutuna bağlıdır. Küresel denetim akışları analiz karmaşıklığına bağlıdır, çünkü saat sürebilirprogram ve tüm kütüphanelerde her yöntemi.

Neden tüm program analiz etmek zorunda değildir, ve hatta daha ciddi abarttı ucuz bir analiz yapmak değil mi? Bu çok zor aslında derler doğru bir program yazmak yapmaz çalışan bir algoritma önerilmiş ve tasarım ekibi bunu göz önünde bulundurun. Bu tür herhangi bir algoritma bilmiyorum.

Şimdi, yorumcu gösteriyor "yapıcı tüm alanları denemeyin". O kadar da kötü bir fikir değil. Aslında, bu kötü bir fikir buC# zaten yapılar için bu özelliği vardır. Yapı kesinlikle bir kurucu ata zaman tüm alanları döndürür decimal normalde için gereklidir; varsayılan oluşturucu varsayılan değerlerine tüm alanları başlatır.

Derslerimiz ne olacak? Pekinasıl yapıcı bir alanı başlatıldı? Bu decimal bir çağrı olabilirsanal bir yöntemalanları başlatmak için, ve şimdi önce biz aynı pozisyonda geri döndük. Yapılar türetilmiş sınıfları yok; sınıflar olabilir. Bir kütüphane soyut bir sınıf içeren tüm alanları başlatan bir kurucu içeren gerekli midir? Ne kadar soyut sınıf alanları için başlatılması gerektiğini biliyor mu?

John alanları başlatılır önce sadece arama yöntemleri yasaklayan-doktora önerir. Yani, özetle, bizim seçenekleri vardır:

  • Sık, sık kullanılan güvenli programlama cümleler yasadışı olun.
  • Derleme muhtemelen orada değil mi böceklere bakmak için saat yapar tüm program pahalı bir analiz yapmak.
  • Varsayılan değerler için otomatik başlatma güvenmek.

Tasarım ekibi üçüncü seçeneği seçti.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • How It Should Have Ended

    How It Shoul

    5 Mart 2007
  • kev5124

    kev5124

    9 Kasım 2008
  • Simon Hayter

    Simon Hayter

    20 HAZİRAN 2010