Saya sedang menulis kode ini:
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.");
}
}
Dan terkejut menemukan kesalahan kompilasi:
Variabel lokal bernama 'tindakan' sudah didefinisikan dalam lingkup ini
Itu adalah masalah yang cukup mudah untuk diselesaikan; menyingkirkan yang kedua varsudah cukup.
Jelas variabel yang dideklarasikan dalam caseblok memiliki ruang lingkup induk switch, tapi saya ingin tahu mengapa ini. Mengingat bahwa C # tidak memungkinkan eksekusi jatuh melalui kasus-kasus lain (itu membutuhkan break , return, throw, atau goto casepernyataan pada akhir setiap caseblok), tampaknya cukup aneh bahwa hal itu akan memungkinkan deklarasi variabel di dalam salah satu caseuntuk digunakan atau konflik dengan variabel di lain case. Dengan kata lain variabel tampaknya jatuh melalui casepernyataan meskipun eksekusi tidak bisa. C # bersusah payah untuk mempromosikan keterbacaan dengan melarang beberapa konstruksi bahasa lain yang membingungkan atau mudah disalahgunakan. Tapi ini sepertinya hanya menyebabkan kebingungan. Pertimbangkan skenario berikut:
Jika ingin mengubahnya menjadi ini:
case BindingType.Inherited: var action = (byte)ChangeAction.Inherit; return (x => x.Action == action); case BindingType.ExplicitValue: return (x => x.Action == action);Saya mendapatkan " Penggunaan 'tindakan' variabel lokal yang belum ditetapkan ". Ini membingungkan karena dalam setiap konstruksi lain di C # yang dapat saya pikirkan
var action = ...akan menginisialisasi variabel, tetapi di sini hanya menyatakannya.Jika saya menukar kasus seperti ini:
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);Saya mendapatkan " Tidak dapat menggunakan 'tindakan' variabel lokal sebelum dideklarasikan ". Jadi urutan blok kasus tampaknya penting di sini dengan cara yang tidak sepenuhnya jelas - Biasanya saya bisa menulis ini dalam urutan apa pun yang saya inginkan, tetapi karena
varharus muncul di blok pertama di manaactiondigunakan, saya harus mengubahcaseblok demikian.Jika ingin mengubahnya menjadi ini:
case BindingType.Inherited: var action = (byte)ChangeAction.Inherit; return (x => x.Action == action); case BindingType.ExplicitValue: action = (byte)ChangeAction.SetValue; goto case BindingType.Inherited;Maka saya tidak mendapatkan kesalahan, tetapi dalam arti, sepertinya variabel diberi nilai sebelum dideklarasikan.
(Meskipun saya tidak dapat memikirkan kapan pun Anda benar-benar ingin melakukan ini - saya bahkan tidak tahugoto caseada sebelum hari ini)
Jadi pertanyaan saya adalah, mengapa para desainer C # tidak memberikan caseruang lingkup lokal mereka sendiri? Apakah ada alasan historis atau teknis untuk ini?
switchsama sekali - Saya hanya ingin tahu tentang alasan di balik desain ini.
breaktidak mungkin dalam C #.
actionvariabel Anda sebelumswitchpernyataan, atau masukkan setiap case ke dalam kurungannya sendiri, dan Anda akan mendapatkan perilaku yang masuk akal.