Bu kodu yazıyordum:
private static Expression<Func<Binding, bool>> ToExpression(BindingCriterion criterion)
{
switch (criterion.ChangeAction)
{
case BindingType.Inherited:
var action = (byte)ChangeAction.Inherit;
return (x => x.Action == action);
case BindingType.ExplicitValue:
var action = (byte)ChangeAction.SetValue;
return (x => x.Action == action);
default:
// TODO: Localize errors
throw new InvalidOperationException("Invalid criterion.");
}
}
Ve bir derleme hatası bulmak şaşırttı:
'Action' adlı bir yerel değişken zaten bu kapsamda tanımlandı
Çözülmesi oldukça kolay bir sorundu; Sadece ikinciden kurtulmak variçin hile yaptım.
Açıkça görüldüğü üzere , casebloklar halinde bildirilen değişkenler ebeveynin kapsamına sahiptir switch, ancak bunun neden olduğunu merak ediyorum. C # yürütme (diğer durumlarda üzerinden düşmesine izin vermez göz önüne alındığında gerektirir break , return, throw, veya goto caseher sonunda ifadeleri casebloğu), bu bir iç değişken bildirimleri izin vereceğini oldukça tuhaf görünüyor casebaşka değişkenler ile birlikte kullanıldığında veya çatışma edilecek case. Başka bir deyişle, caseyürütmenin yapamamasına rağmen değişkenlerin ifadelerden geçtiği görülmektedir . C # kafa karıştırıcı veya veya kolayca kötüye kullanılan diğer dillerin bazı yapılarını yasaklayarak okunabilirliği artırmak için büyük acılar çekiyor. Ancak bu karışıklığa neden olması zor gibi görünüyor. Aşağıdaki senaryoları göz önünde bulundurun:
Eğer bunu değiştirecekseydi:
case BindingType.Inherited: var action = (byte)ChangeAction.Inherit; return (x => x.Action == action); case BindingType.ExplicitValue: return (x => x.Action == action);" Atanmamış yerel değişkenin 'action' kullanımı " alıyorum . Bu kafa karıştırıcı çünkü C # 'daki diğer tüm yapılarda, düşünebildiğim
var action = ...değişken değişkeni başlatabilir , ancak burada basitçe bildirir.Eğer böyle davaları değiştirirsem:
case BindingType.ExplicitValue: action = (byte)ChangeAction.SetValue; return (x => x.Action == action); case BindingType.Inherited: var action = (byte)ChangeAction.Inherit; return (x => x.Action == action);" Yerel değişken 'eylemini' bildirilmeden önce kullanamıyorum " alıyorum . Bu yüzden kasa bloklarının sırası burada tamamen açık olmayan bir şekilde önemli gibi görünüyor - Normalde bunları istediğim herhangi bir sırayla yazabilirim, ancak kullanılan
varilk blokta görünmesi gerektiğinden bloklarıactiondeğiştirmek zorundayım.casebuna göre.Eğer bunu değiştirecekseydi:
case BindingType.Inherited: var action = (byte)ChangeAction.Inherit; return (x => x.Action == action); case BindingType.ExplicitValue: action = (byte)ChangeAction.SetValue; goto case BindingType.Inherited;Sonra hata alamadım, ancak bir anlamda değişkene ilan edilmeden önce bir değer atanmış gibi görünüyor .
(Gerçekte bunu yapmak istediğinizi asla düşünemesem de -goto casebugünden önce varlığımı bile bilmiyordum )
Öyleyse benim sorum şu, neden C # tasarımcıları casekendi yerel alanlarını engellemedi? Bunun tarihsel veya teknik bir sebebi var mı?
switch- Sadece bu tasarımın arkasındaki mantığı merak ediyorum.
break.
actionönce değişkeniswitchaçıklamada, yoksa kendi parantez içine her durumda koymak ve mantıklı davranış olacaktır.