Saya ingin mencoba mengubah string menjadi Guid, tetapi saya tidak ingin bergantung pada menangkap pengecualian (
- karena alasan kinerja - pengecualian mahal
- untuk alasan kegunaan - debugger akan muncul
- untuk alasan desain - yang diharapkan tidak luar biasa
Dengan kata lain kodenya:
public static Boolean TryStrToGuid(String s, out Guid value)
{
try
{
value = new Guid(s);
return true;
}
catch (FormatException)
{
value = Guid.Empty;
return false;
}
}
tidak cocok.
Saya akan mencoba menggunakan RegEx, tetapi karena panduan dapat dibungkus tanda kurung, dibungkus kurung, tidak ada yang dibungkus, membuatnya sulit.
Selain itu, saya pikir nilai Guid tertentu tidak valid (?)
Perbarui 1
ChristianK punya ide bagus untuk menangkap saja FormatException
, daripada semua. Mengubah contoh kode pertanyaan untuk menyertakan saran.
Perbarui 2
Mengapa khawatir tentang pengecualian yang dilemparkan? Apakah saya benar-benar mengharapkan GUID tidak valid sesering itu?
Jawabannya adalah ya . Itulah mengapa saya menggunakan TryStrToGuid - Saya sedang mengharapkan data yang buruk.
Contoh 1 Ekstensi ruang nama dapat ditentukan dengan menambahkan GUID ke nama folder . Saya mungkin parsing nama folder, memeriksa untuk melihat apakah teks setelah final . adalah GUID.
c:\Program Files
c:\Program Files.old
c:\Users
c:\Users.old
c:\UserManager.{CE7F5AA5-6832-43FE-BAE1-80D14CD8F666}
c:\Windows
c:\Windows.old
Contoh 2 Saya mungkin menjalankan server web yang banyak digunakan ingin memeriksa validitas beberapa data yang diposkan kembali. Saya tidak ingin data yang tidak valid mengikat sumber daya 2-3 pesanan lebih besar dari yang seharusnya.
Contoh 3 Saya mungkin mem-parsing ekspresi pencarian yang dimasukkan oleh pengguna.
Jika mereka memasukkan GUID, saya ingin memprosesnya secara khusus (seperti mencari objek itu secara khusus, atau menyorot dan memformat istilah pencarian tertentu dalam teks respons.)
Perbarui 3 - Tolok ukur kinerja
Uji konversi 10.000 Panduan yang baik, dan 10.000 Panduan yang buruk.
Catch FormatException:
10,000 good: 63,668 ticks
10,000 bad: 6,435,609 ticks
Regex Pre-Screen with try-catch:
10,000 good: 637,633 ticks
10,000 bad: 717,894 ticks
COM Interop CLSIDFromString
10,000 good: 126,120 ticks
10,000 bad: 23,134 ticks
ps saya tidak perlu membenarkan pertanyaan.
4.0
. Itu sebabnya pertanyaan, dan jawaban yang diterima, adalah cara mereka.Jawaban:
Tolok Ukur Kinerja
COM Intertop (Tercepat) Jawaban:
Intinya: Jika Anda perlu memeriksa apakah string adalah panduan, dan Anda peduli tentang kinerja, gunakan COM Interop.
Jika Anda perlu mengonversi panduan dalam representasi String ke Panduan, gunakan
sumber
Setelah .net 4.0 tersedia, Anda dapat menggunakan
Guid.TryParse()
.sumber
Anda tidak akan menyukai ini, tetapi apa yang membuat Anda berpikir bahwa menangkap pengecualian akan menjadi lebih lambat?
Berapa banyak upaya gagal untuk menguraikan GUID yang Anda harapkan dibandingkan dengan yang berhasil?
Saran saya adalah gunakan fungsi yang baru saja Anda buat dan profil kode Anda. Jika Anda menemukan bahwa fungsi ini benar-benar hotspot maka perbaiki tetapi tidak sebelumnya.
sumber
Di .NET 4.0 Anda dapat menulis sebagai berikut:
sumber
Setidaknya saya akan menulis ulang sebagai:
Anda tidak ingin mengatakan "GUID tidak valid" pada SEHException, ThreadAbortException atau hal-hal fatal atau tidak terkait lainnya.
Pembaruan : Dimulai dengan .NET 4.0, ada serangkaian metode baru yang tersedia untuk Guid:
Guid.TryParse
Guid.TryParseExact
Sungguh, itu harus digunakan (jika hanya untuk fakta, bahwa mereka tidak "naif" diimplementasikan menggunakan try-catch secara internal).
sumber
Interop lebih lambat dari sekedar menangkap pengecualian:
Di jalan yang bahagia, dengan 10.000 Panduan:
Di jalan yang tidak bahagia:
Ini lebih konsisten, tetapi juga lebih lambat secara konsisten. Menurut saya, Anda sebaiknya mengkonfigurasi debugger Anda hanya untuk istirahat pada pengecualian yang tidak tertangani.
sumber
Nah, inilah regex yang Anda butuhkan ...
Tapi itu hanya untuk pemula. Anda juga harus memverifikasi bahwa berbagai bagian seperti tanggal / waktu berada dalam rentang yang dapat diterima. Saya tidak bisa membayangkan ini menjadi lebih cepat daripada metode coba / tangkap yang telah Anda uraikan. Semoga Anda tidak menerima banyak GUID yang tidak valid untuk menjamin jenis cek ini!
sumber
Jika Anda akan mencoba pendekatan coba / tangkap, Anda dapat menambahkan atribut [System.Diagnostics.DebuggerHidden] untuk memastikan debugger tidak merusak bahkan jika Anda telah menetapkannya untuk istirahat saat melempar.
sumber
Sementara itu adalah benar bahwa menggunakan kesalahan lebih mahal, kebanyakan orang percaya bahwa mayoritas GUID mereka akan menjadi komputer yang dihasilkan sehingga
TRY-CATCH
tidak terlalu mahal karena hanya menghasilkan biaya padaCATCH
. Anda dapat membuktikan ini pada diri sendiri dengan tes sederhana keduanya (pengguna publik, tanpa kata sandi).Ini dia:
sumber
Saya memiliki situasi yang sama dan saya perhatikan bahwa hampir tidak pernah ada string 36 karakter yang tidak valid. Jadi berdasarkan fakta ini, saya sedikit mengubah kode Anda untuk mendapatkan kinerja yang lebih baik sambil tetap membuatnya sederhana.
sumber
Sejauh yang saya tahu, tidak ada sesuatu seperti Guid.TryParse di mscrolib. Menurut Sumber Referensi, tipe Guid memiliki konstruktor mega-kompleks yang memeriksa semua jenis format panduan dan mencoba untuk menguraikannya. Tidak ada metode pembantu yang bisa Anda panggil, bahkan melalui refleksi. Saya pikir Anda harus mencari parser Guid pihak ketiga, atau menulis sendiri.
sumber
Jalankan potensi GUID melalui RegEx atau beberapa kode kustom yang melakukan pemeriksaan kewarasan untuk memastikan strig setidaknya terlihat seperti GUID dan hanya terdiri dari karakter yang valid (dan mungkin sepertinya cocok dengan format keseluruhan). Jika tidak lulus pemeriksaan kewarasan, kembalikan kesalahan - yang mungkin akan menyingkirkan sebagian besar string tidak valid.
Kemudian konversi string seperti yang Anda miliki di atas, masih menangkap pengecualian untuk beberapa string tidak valid yang melewati pemeriksaan kewarasan.
Jon Skeet melakukan analisis untuk sesuatu yang mirip dengan parsing Ints (sebelum TryParse ada dalam Framework): Memeriksa apakah string dapat dikonversi ke Int32
Namun, seperti yang ditunjukkan AnthonyWJones Anda mungkin tidak perlu khawatir tentang ini.
sumber
sumber
Ctor Guid adalah regex yang dikompilasi, sehingga Anda akan mendapatkan perilaku yang sama persis tanpa pengecualian.
Bahkan solusi yang lebih keren adalah dengan instrumen dinamis metode, dengan mengganti "melemparkan baru" dengan cepat.
sumber
Saya memilih tautan GuidTryParse yang diposting di atas oleh Jon atau solusi serupa (IsProbablyGuid). Saya akan menulis yang seperti itu untuk perpustakaan Konversi saya.
Saya pikir itu benar-benar lumpuh bahwa pertanyaan ini harus sangat rumit. Kata kunci "is" atau "as" akan baik-baik saja JIKA seorang Guid bisa menjadi nol. Tetapi untuk beberapa alasan, meskipun SQL Server tidak masalah dengan itu, .NET tidak. Mengapa? Berapa nilai Guid.Empty? Ini hanya masalah konyol yang dibuat oleh desain. NET, dan itu benar-benar mengganggu saya ketika konvensi bahasa menginjak dirinya sendiri. Jawaban berkinerja terbaik sejauh ini telah menggunakan COM Interop karena Framework tidak menanganinya dengan anggun? "Bisakah string ini menjadi GUID?" harus menjadi pertanyaan yang mudah dijawab.
Mengandalkan pengecualian yang dilemparkan tidak apa-apa, sampai aplikasi berjalan di internet. Pada saat itu saya hanya mengatur diri saya untuk penolakan serangan layanan. Bahkan jika saya tidak "diserang", saya tahu beberapa yahoo akan mengunggah URL, atau mungkin departemen pemasaran saya akan mengirimkan tautan yang salah, dan kemudian aplikasi saya harus mengalami kinerja yang lumayan kuat yang BISA dibawa ke server karena saya tidak menulis kode saya untuk menangani masalah yang TIDAK HARUS terjadi, tetapi kita semua tahu AKAN TERJADI.
Ini mengaburkan garis sedikit pada "Pengecualian" - tetapi intinya, bahkan jika masalahnya jarang terjadi, jika itu bisa terjadi cukup banyak dalam jangka waktu pendek sehingga aplikasi Anda crash melayani tangkapan dari itu semua, maka saya pikir melempar pengecualian adalah bentuk buruk.
TheRage3K
sumber
jika Typet dari ctype (myvar, Object) Is Guid maka .....
sumber
sumber
Dengan metode ekstensi dalam C #
sumber