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 var
için hile yaptım.
Açıkça görüldüğü üzere , case
bloklar 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 case
her sonunda ifadeleri case
bloğu), bu bir iç değişken bildirimleri izin vereceğini oldukça tuhaf görünüyor case
başka değişkenler ile birlikte kullanıldığında veya çatışma edilecek case
. Başka bir deyişle, case
yü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
var
ilk blokta görünmesi gerektiğinden bloklarıaction
değiştirmek zorundayım.case
buna 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 case
bugünden önce varlığımı bile bilmiyordum )
Öyleyse benim sorum şu, neden C # tasarımcıları case
kendi 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şkeniswitch
açıklamada, yoksa kendi parantez içine her durumda koymak ve mantıklı davranış olacaktır.