Apakah ada cara untuk melewati beberapa pernyataan kasus tanpa menyatakan case value:
berulang kali?
Saya tahu ini bekerja:
switch (value)
{
case 1:
case 2:
case 3:
// Do some stuff
break;
case 4:
case 5:
case 6:
// Do some different stuff
break;
default:
// Default stuff
break;
}
tapi saya ingin melakukan sesuatu seperti ini:
switch (value)
{
case 1,2,3:
// Do something
break;
case 4,5,6:
// Do something
break;
default:
// Do the Default
break;
}
Apakah sintaks ini yang saya pikirkan dari bahasa yang berbeda, atau saya kehilangan sesuatu?
c#
switch-statement
theo
sumber
sumber
,
dan yang tidak dibagi dengan bahasa c-style lainnya. Bagi saya itu tampak lebih kotor.Jawaban:
Tidak ada sintaks dalam C ++ atau C # untuk metode kedua yang Anda sebutkan.
Tidak ada yang salah dengan metode pertama Anda. Namun jika Anda memiliki rentang yang sangat besar, gunakan saja serangkaian pernyataan if.
sumber
Saya kira ini sudah dijawab. Namun, saya pikir Anda masih dapat mencampur kedua opsi dengan cara yang lebih baik secara sintaksis dengan melakukan:
sumber
Sintaks ini dari Visual Basic Select ... Pernyataan Kasus :
Anda tidak dapat menggunakan sintaks ini dalam C #. Sebagai gantinya, Anda harus menggunakan sintaks dari contoh pertama Anda.
sumber
Dalam C # 7 (tersedia secara default di Visual Studio 2017 / .NET Framework 4.6.2), beralih berbasis jangkauan sekarang mungkin dengan pernyataan switch dan akan membantu dengan masalah OP.
Contoh:
Catatan:
(
dan)
tidak diperlukan dalamwhen
kondisi, tetapi digunakan dalam contoh ini untuk menyoroti perbandingan.var
juga dapat digunakan sebagai penggantiint
. Sebagai contoh:case var n when n >= 7:
.sumber
Anda dapat meninggalkan baris baru yang memberi Anda:
tapi saya menganggap gaya buruk itu.
sumber
.NET Framework 3.5 memiliki rentang:
Enumerable.Range dari MSDN
Anda dapat menggunakannya dengan "berisi" dan pernyataan IF, karena seperti seseorang mengatakan pernyataan SWITCH menggunakan operator "==".
Berikut sebuah contoh:
Tapi saya pikir kita bisa bersenang-senang lagi: karena Anda tidak akan memerlukan nilai kembali dan tindakan ini tidak mengambil parameter, Anda dapat dengan mudah menggunakan tindakan!
Contoh lama dengan metode baru ini:
Karena Anda melewati tindakan, bukan nilai, Anda harus menghilangkan tanda kurung, itu sangat penting. Jika Anda membutuhkan fungsi dengan argumen, cukup ubah jenis
Action
keAction<ParameterType>
. Jika Anda perlu mengembalikan nilai, gunakanFunc<ParameterType, ReturnType>
.Dalam C # 3.0 tidak ada Aplikasi Partial yang mudah untuk merangkum fakta parameter kasusnya sama, tetapi Anda membuat metode pembantu kecil (sedikit verbose, tho).
Berikut ini contoh bagaimana pernyataan fungsional baru yang diimpor adalah IMHO lebih kuat dan elegan daripada yang imperatif lama.
sumber
int start
danint count
. Contoh-contoh Anda tidak akan berfungsi sebagaimana mestinya. Anda menulisnya seolah argumen kedua adalahint end
. Misalnya -Enumerable.Range(11,20)
akan menghasilkan 20 angka yang dimulai dengan 11, dan bukan angka dari 11 hingga 20.Enumerable.Range(11,20).Contains(c)
setara denganfor(int i = 11; i < 21; ++i){ if (i == c) return true; } return false;
Jika Anda memiliki jangkauan besar, itu akan memakan waktu lama, sementara hanya menggunakan>
dan<
akan cepat dan waktu yang konstan.MySwitchWithEnumerable
pengembalianvoid
adalah desain yang lemah untuk situasi ini. ALASAN: Anda telah mengonversikanif-else
serangkaian pernyataan independen - yang menyembunyikan maksudnya, yaitu bahwa keduanya saling eksklusif - hanya satuaction
yang dieksekusi. Sebaliknya kembalibool
, dengan tubuhif (..) { action(); return true; } else return false;
Situs memanggil kemudian menunjukkan niat:if (MySwitchWithEnumerable(..)) else (MySwitchWithEnumerable(..));
. Ini lebih disukai. Namun, ini juga bukan lagi peningkatan yang signifikan dibandingkan versi asli Anda, untuk kasus sederhana ini.Inilah solusi lengkap C # 7 ...
Ia bekerja dengan string juga ...
sumber
Kode di bawah ini tidak berfungsi:
Satu-satunya cara untuk melakukan ini adalah:
Kode yang Anda cari berfungsi di Visual Basic di mana Anda dapat dengan mudah memasukkan rentang ... dalam
none
opsiswitch
pernyataan atauif else
blok yang nyaman, saya sarankan, pada titik yang sangat ekstrim, buat .dll dengan Visual Basic dan impor kembali ke proyek C # Anda.Catatan: setara saklar di Visual Basic adalah
Select Case
.sumber
Pilihan lain adalah menggunakan rutinitas. Jika case 1-3 semuanya menjalankan logika yang sama maka bungkus logika itu dalam suatu rutin dan panggil untuk setiap case. Saya tahu ini tidak benar-benar menghilangkan pernyataan kasus, tetapi menerapkan gaya yang baik dan menjaga pemeliharaan tetap minimum .....
[Sunting] Menambahkan implementasi alternatif untuk mencocokkan pertanyaan asli ... [/ Edit]
Alt
sumber
Satu sisi yang kurang dikenal dari saklar di C # adalah bahwa ia bergantung pada operator = dan karena itu dapat diganti Anda bisa memiliki sesuatu seperti ini:
sumber
gcc mengimplementasikan ekstensi ke bahasa C untuk mendukung rentang berurutan:
Sunting : Hanya memperhatikan tag C # pada pertanyaan, jadi mungkin jawaban gcc tidak membantu.
sumber
Di C # 7 kami sekarang memiliki Pencocokan Pola sehingga Anda dapat melakukan sesuatu seperti:
sumber
Sebenarnya saya tidak suka perintah GOTO juga, tetapi ini dalam materi Microsoft resmi, dan di sini semua sintaks diizinkan.
Jika titik akhir daftar pernyataan bagian switch dapat dijangkau, kesalahan waktu kompilasi terjadi. Ini dikenal sebagai aturan "no fall through". Contoh
valid karena tidak ada bagian sakelar yang memiliki titik akhir yang dapat dijangkau. Tidak seperti C dan C ++, eksekusi bagian switch tidak diizinkan untuk "jatuh" ke bagian switch berikutnya, dan contohnya
menghasilkan kesalahan waktu kompilasi. Ketika eksekusi bagian switch harus diikuti dengan eksekusi bagian switch lain, kasus goto eksplisit atau pernyataan default goto harus digunakan:
Beberapa label diizinkan di bagian sakelar. Contoh
Saya percaya pada kasus khusus ini, GOTO dapat digunakan, dan itu sebenarnya satu-satunya cara untuk jatuh.
Sumber: http://msdn.microsoft.com/en-us/library/aa664749%28v=vs.71%29.aspx
sumber
goto
hampir selalu dapat dihindari (meskipun saya tidak menganggapnya "mengerikan" di sini - itu mengisi peran khusus, terstruktur,). Dalam contoh Anda, karena Anda telah membungkus tubuh case dalam fungsi (hal yang baik), case 0 dapat menjadiCaseZero(); CaseZeroOrOne(); break;
. Tidakgoto
diperlukanBanyak sekali pekerjaan tampaknya telah dimasukkan ke dalam mencari cara untuk mendapatkan salah satu sintaks C # paling tidak digunakan untuk entah bagaimana terlihat lebih baik atau bekerja lebih baik. Secara pribadi saya menemukan pernyataan beralih jarang layak digunakan. Saya sangat menyarankan untuk menganalisis data apa yang Anda uji dan hasil akhir yang Anda inginkan.
Misalnya, Anda ingin menguji nilai dengan cepat dalam rentang yang diketahui untuk melihat apakah itu bilangan prima. Anda ingin menghindari kode Anda melakukan perhitungan boros dan Anda dapat menemukan daftar bilangan prima dalam rentang yang Anda inginkan online. Anda bisa menggunakan pernyataan peralihan besar-besaran untuk membandingkan setiap nilai dengan bilangan prima yang diketahui.
Atau Anda bisa saja membuat peta array bilangan prima dan mendapatkan hasil langsung:
Mungkin Anda ingin melihat apakah karakter dalam string adalah heksadesimal. Anda bisa menggunakan statement switch yang jelek dan agak besar.
Atau Anda bisa menggunakan ekspresi reguler untuk menguji char atau menggunakan fungsi IndexOf untuk mencari char dalam serangkaian huruf heksadesimal yang diketahui:
Katakanlah Anda ingin melakukan salah satu dari 3 tindakan berbeda tergantung pada nilai yang akan menjadi kisaran 1 hingga 24. Saya akan menyarankan menggunakan seperangkat pernyataan IF. Dan jika itu menjadi terlalu kompleks (Atau angkanya lebih besar seperti 5 tindakan berbeda tergantung pada nilai dalam kisaran 1 hingga 90) maka gunakan enum untuk menentukan tindakan dan membuat peta susunan enum. Nilai tersebut kemudian akan digunakan untuk mengindeks ke dalam peta array dan mendapatkan enum dari tindakan yang Anda inginkan. Kemudian gunakan baik set kecil pernyataan IF atau pernyataan beralih yang sangat sederhana untuk memproses nilai enum yang dihasilkan.
Selain itu, hal yang menyenangkan tentang sebuah array map yang mengubah serangkaian nilai menjadi aksi adalah ia dapat dengan mudah diubah oleh kode. Dengan kode berkabel, Anda tidak dapat dengan mudah mengubah perilaku saat runtime tetapi dengan peta larik itu mudah.
sumber
Hanya untuk menambah percakapan, menggunakan .NET 4.6.2 saya juga bisa melakukan hal berikut. Saya menguji kodenya dan itu berhasil untuk saya.
Anda juga dapat melakukan beberapa pernyataan "ATAU", seperti di bawah ini:
Anda juga dapat memeriksa apakah cocok dengan nilai dalam array:
sumber
Jika Anda memiliki jumlah string yang sangat besar (atau tipe lainnya) semua melakukan hal yang sama, saya merekomendasikan penggunaan daftar string yang dikombinasikan dengan string. Properti berisi.
Jadi, jika Anda memiliki pernyataan beralih besar seperti:
Anda mungkin ingin menggantinya dengan
if
pernyataan seperti ini:Skala ini baik untuk sejumlah kasus tali.
sumber
Saya pikir ini lebih baik di C # 7 atau di atas.
Anda juga dapat memeriksa Rentang dalam kasing C #: Ganti kasing: dapatkah saya menggunakan rentang alih-alih satu nomor atau jika Anda ingin memahami dasar-dasar kasing C #
sumber
Untuk ini, Anda akan menggunakan pernyataan goto. Seperti:
sumber
goto
. Lebih buruk lagi, ini adalah penggunaan yang sama sekali tidak perlugoto
, karena sintaks asli yang dinyatakan oleh OP berfungsi. Pertanyaannya adalah apakah ada cara yang lebih ringkas untuk memberikan kasus pengganti. Seperti yang orang-orang jawab bertahun-tahun sebelum Anda melakukannya , ya ada - jika Anda bersedia meletakkan beberapa kasing dalam satu bariscase 1: case 2:
, dan jika gaya editor otomatis memungkinkan.