Saat mem-parsing input pengguna, umumnya disarankan untuk tidak melempar dan menangkap pengecualian melainkan menggunakan metode validasi. Di .NET BCL, ini akan menjadi perbedaan antara, misalnya, int.Parse
(melempar pengecualian pada data tidak valid) dan int.TryParse
(mengembalikan false
data tidak valid).
Saya merancang sendiri
Foo.TryParse(string s, out Foo result)
metode dan saya tidak yakin tentang nilai pengembalian. Saya bisa menggunakan metode bool
seperti .NET sendiri TryParse
, tetapi itu tidak akan memberikan indikasi tentang jenis kesalahan, tentang alasan yang tepat mengapa s
tidak dapat diuraikan menjadi Foo
. (Misalnya, s
bisa memiliki tanda kurung yang tidak cocok, atau jumlah karakter yang salah, atau Bar
tanpa yang sesuai Baz
, dll.)
Sebagai pengguna API, saya sangat tidak suka metode yang hanya mengembalikan Boolean sukses / gagal tanpa memberi tahu saya mengapa operasi gagal. Ini menjadikan debugging permainan tebak-tebakan, dan saya juga tidak ingin memaksakan itu pada klien perpustakaan saya.
Saya dapat memikirkan banyak solusi untuk masalah ini (mengembalikan kode status, mengembalikan string kesalahan, menambahkan string kesalahan sebagai parameter keluar), tetapi mereka semua memiliki kelemahan masing-masing, dan saya juga ingin tetap konsisten dengan konvensi Framework .NET .
Jadi, pertanyaan saya adalah sebagai berikut:
Apakah ada metode dalam .NET Framework yang (a) mengurai input tanpa melempar pengecualian dan (b) masih mengembalikan informasi kesalahan yang lebih terperinci daripada Boolean benar / salah sederhana?
sumber
Parse()
.Jawaban:
Saya akan merekomendasikan menggunakan pola monad untuk tipe pengembalian Anda.
ParseResult<Foo> foo = FooParser.Parse("input");
Perhatikan juga, seharusnya bukan tanggung jawab Foo untuk mencari tahu bagaimana seharusnya diuraikan dari input pengguna karena ini secara langsung mengikat lapisan domain Anda ke lapisan UI Anda, dan juga melanggar prinsip tanggung jawab tunggal.
Anda juga bisa membuat kelas hasil parse khusus untuk
Foo
daripada menggunakan generik, tergantung pada kasus penggunaan Anda.Kelas hasil parse spesifik foo mungkin terlihat seperti ini:
Ini adalah versi Monad:
Saya tidak mengetahui adanya metode dalam kerangka kerja .net yang mengembalikan informasi kesalahan parse terperinci.
sumber
Foo.ToString
danFoo.Parse
.Func<T>
akan memenuhi kriteria itu, jika Anda memasukkanT
informasi yang Anda butuhkan. Mengembalikan informasi kesalahan terperinci sebagian besar terserah Anda. Sudahkah Anda mempertimbangkan untuk menggunakanMaybe<T>
? Lihat mikhail.io/2016/01/monads-explained-in-csharpAnda bisa melihat ModelState dalam kerangka kerja MVC. Ini mewakili percobaan beberapa input dan mungkin memiliki kumpulan kesalahan.
Yang mengatakan, saya tidak berpikir ada pola berulang untuk ini di. SM BCL, karena pengecualian adalah - untuk lebih baik atau lebih buruk - pola yang ditetapkan untuk melaporkan kondisi kesalahan dalam .net. Saya pikir Anda harus melanjutkan dan mengimplementasikan solusi Anda sendiri yang sesuai dengan masalah Anda, misalnya
ParseResult
kelas dengan dua subclass,SuccessfulParse
danFailedParse
, di manaSuccessfulParse
memiliki properti dengan nilai parsed danFailedParse
memiliki properti pesan kesalahan. Menggabungkan ini dengan pencocokan pola di C # 7 bisa sangat elegan.sumber
Saya mengalami masalah serupa dengan keinginan untuk menggunakan
TryParse/Convert/etc.
metode di mana saya kadang - kadang perlu tahu bagaimana dan mengapa itu gagal.Saya akhirnya mengambil inspirasi dari bagaimana beberapa serializers menangani kesalahan dan menggunakan acara. Dengan cara ini sintaks untuk
TryX(..., out T)
metode saya terlihat bersih seperti yang lain dan andal mengembalikan sederhanafalse
seperti yang tersirat pola.Namun, ketika saya ingin memerlukan detail lebih lanjut, saya hanya menambahkan Event Handler dan mendapatkan hasil apa pun yang saya butuhkan dalam paket yang kompleks atau sederhana seperti yang saya inginkan (di
MyEventArgs
bawah). Tambahkan ke daftar string, tambahkanExceptionDispatchInfo
dan tangkap Pengecualian; biarkan penelepon memutuskan jika dan bagaimana ia ingin berurusan dengan apa pun yang salah.sumber