2008-11-17 21 views
22

Aşağıdaki kod, "Bu" adlı bir yerel değişken, "çocuk" kapsamında zaten kullanılan 'st' için farklı bir anlam vereceği için bu kapsamda bildirilemez. "Child Scope & CS0136

 string preParent = ""; 
     { 
      string preParent = "Should fail cause we change the meaning"; 
     } 

biz aşağıdakileri yapmayı olsun: Bu işe yaramaz anlıyorum

 var l = new List<string>(); 
     l.Find(st => st.EndsWith("12")); 
     string st = "why this fails?"; 

": adı 'postParent' akımının içinde yok CS0103 başka bir şey belirtmek için ":

 { 
      string postParent=string.Empty; 
     } 
     postParent = "Should this work?"; 

Elde edemediğim şey, derleyicinin postParent'in kapsam dahilinde olmadığını görecek kadar akıllı olmasının nedeni, ancak bir çocuk kapsamı içinde kullanılan değişkenle aynı ada sahip yeni bir değişken tanımlamama izin vermemesidir (Bu noktada açıkça kapsam dışıdır).

Değişkeni kullanmama izin vermeyi reddederek derleyici basit zorlama kapsamı var mı? Eğer öyleyse bu mantıklı.

===========

Düzenlendi:

ben ne de ilginç buluyorum bunu, tek yöntemde iki çocuk kapsamları içinde aynı değişkene sahip olabilir nasıl olduğunu tahmin Bu geçerlidir:

 { 
      string thisWorks= string.Empty; 
     } 
     { 
      string thisWorks= "Should this work?"; 
     } 

sadece sürece (bir ağaç olarak kapsam bakarsak) aynı düzeydedir aynı adı taşıyan iki değişken olabilir bu biraz merak ediyorum. Bu, mantıklıdır çünkü aynı isimde aynı sınıfın iki yönteminde yerel değişkenlere sahip olabilirsiniz.

Sadece postParent değişkenine izin vermezken derleyicinin bunu ayırt edebilmesine ve buna izin vermesine şaşırdım. Bu teknik bir sınırlama mı yoksa tasarım kararı mıydı? Ben gerçekten bu yüzden almak için çalışıyorum ,-)

+2

Neden 5 aydan sonra düşüş var? – JoshBerke

cevap

12

Evet, derleyici kapsamı zorluyor. Bir değişkenin kapsamının, yalnızca bildirimin yapıldığı noktadan değil, tüm kapsamından kaynaklanan kısmi blok olduğunu unutmayın.

Derleyici, postParent numaralı öğeye atama kapsamının dışında olduğu için şikayetçidir (yalnızca iç içe geçmiş parantezler). Şu anda postParent'a atandığınız noktada yeni bir değişken bildirmeye çalışmışsanız, sorun iç içe geçmiş blokta olurdu; çünkü postParent kapsamı, bildirimin önündeyse de iç içe geçmiş bloğu içerecektir.

Kapsamlar, C# 3.0 belirtiminin 3.7 bölümünde anlatılmaktadır.

DÜZENLEME: Sorunuza yanıt vermek için.

Sadece iki basit kural var: blok aynı adı taşıyan başka bir yerel değişken kapsamı

  • yerel değişkenin kapsamı içinde olduğunda bir yerel değişken bildiren edemez

    • olduğu deklarasyon

    Ben dil kapsamı sadece ilanının noktasında başladığı böyle tasarlanmış olabilir, ama bu sadece taşları olarak kapsamları dikkate almak (dil karmaşıklığı açısından) daha basit olduğunu düşünüyorum eminim oluşur - bu yüzden bildirilen tüm yerel değişkenler Aynı bloğun aynı kapsamı vardır, örneğin. Bu da yakalanan değişkenler göz önünde bulundurulduğunda hayatı çok daha basit hale getirir - yakalananlar kapsama göre değişir ve yuvalanmış kapsamlar hayatı ilginç kılar ...

    DÜZENLEME: Bu dil özelliğiyle orijinal lambda ifadesi örneği

    bir anonim fonksiyonun opsiyonel anonim fonksiyonlu-imza isimleri tanımlar ve anonim işlev için resmi parametre türlerini isteğe bağlı: - bu bölüm 7.14.1 bu. anonim işlevinin parametrelerinin kapsamı, anonim işlevli anasistemidir. ile birlikte parametre listesi (veriliyorsa), anonim yöntem gövdesi, bir bildirim alanı oluşturur. Bu nedenle, bu kapsamı anonim-yöntem-ifadesini içeren bir yerel değişken, yerel sabit veya parametre adı eşleştirmek için anonim fonksiyonun parametre adını için bir derleme zamanı hatası veya lambda-ifadesi.

    bu yardım ediyor mu?

  • +0

    Bu kuralın uygulanmasının sebebi ne olursa olsun, hala bunun CLR'de bir kusur olduğuna inanıyorum. Anonim yöntemler, içlerinde yaratılan herhangi bir değişkeni başka herhangi bir işlevden kesin olarak destelemelidir, hatta CLR'nin delege yöntemindeki her değişkene bir önek eklemesi kadar basittir. –

    +2

    CLR burada hiç yer almıyor. Bu bir dil kararı. Ve ben tamamen katılmıyorum. Buradaki nokta, dış değişkenlerin anonim işlev için kullanılabilir olmasıdır, bu nedenle anonim işlev, "normal" bir blokta tekrar bildirilmiş gibi, tam olarak aynı şekilde onları yeniden tanımlayamaz. –

    +0

    Bildiri, tüm kapsam bloğunun bir parçası olduğunu varsaydığından, dış değişkenin anonim işleve dönüştürülüp iletilmeyeceğini bilmenin bir yolu olmadığını hissettiğinizden anlam ifade eder. Değişkenin kapsamın kapsamına dayandığında buna izin verilebilir. – JoshBerke

    -2

    Sınırlı bir kapsamda bir değişken bildiriyorsunuz ve bu kapsamı dışında kullanmaya çalışıyorsunuz. Derleyici, ona erişmek istemediğinizi varsayar, böylece dosyada başka bir yerde aynı ada sahip bir değişken bildirebilirsiniz. Değişkeni varsaymanın eski C numarasını yapmaya çalışmanız, kapsamın hemen dışında yaşayacaktır. Örneğin bu, eski C/C++ sürümlerinde çalışır, ancak artık yoktur.

    for (int i=0; i<10; i++) 
    { 
        cout <<”In the loop i is “<< i << endl; 
    } 
    cout << “outside of the loop i is “ << i << endl; //this only compiles with old C/C++ compilers. 
    
    +2

    Yapmaya çalıştığım şey Jared değil ;-) C# bu değişkenin aynı isimle bir değişkeni bildirmesine izin vermez bir çocuk kapsamı içinde beyan edilmiştir. – JoshBerke

    İlgili konular