Apakah perlu memeriksa untuk melihat apakah Guid.NewGuid () adalah Guid.Empty?

28

Dalam salah satu proyek saya sedang mengerjakan pola berikut ini terlihat secara teratur:

var guid = Guid.NewGuid().ToString();
while (guid == Guid.Empty.ToString())
{
    guid = Guid.NewGuid().ToString();
}

Sementara saya mengerti bahwa a GUID tidak dijamin unik dan sesuai dokumentasi MSDN, GUID yang dihasilkan mungkin nol , apakah ini pertimbangan praktis sebenarnya layak untuk mengirim pengujian siklus baik dalam pengertian komputasi maupun dalam hal waktu pengembang memikirkannya ?

rjzii
sumber
1
Jika Anda melihat pola ini berulang kali, mungkin sebuah metode utilitas bisa digunakan? Potongan kode berulang seperti ini sepertinya masalah yang lebih besar daripada kenyataan bahwa Anda memeriksa kasing tepi yang tidak akan pernah terjadi dan mungkin tidak masalah meskipun itu terjadi.
psr
27
Kode itu ada di sana untuk menjauhkan buaya. Apakah ada buaya di mana Anda menulis kode? Tidak? Maka jelas itu berhasil!
Eric Lippert
3
Apapun masalahnya, saya akan melakukan ini dalam waktu-do.
Arturo Torres Sánchez
3
Mengapa Anda mengubah panduan ke string dan kemudian membandingkan? mereka membandingkan denda sendiri.
Andy
2
The dokumentasi telah diperbarui: "Guid itu kembali dijamin Guid.Empty tidak sama."
sschoof

Jawaban:

33

Saya akan menyarankan itu tidak layak memeriksa Guid.Empty. Dokumen untuk Guid.NewGuid untuk beberapa alasan menyebutkan hal itu

Peluang bahwa nilai dari Guid baru adalah semua nol atau sama dengan Guid lainnya sangat rendah.

Guid.NewGuid adalah pembungkus untuk Win32 API CoCreateGuid , yang tidak menyebutkan pengembalian semua nol.

Raymond Chen melangkah lebih jauh , menyarankan itu

tidak ada implementasi CoCreateGuid yang valid yang dapat menghasilkan GUID_NULL

Jadi, tidak, saya tidak akan khawatir tentang itu. Saya tidak akan menebak mengapa Guid. Dokumen baru bahkan menyebutkannya.

Curt Nichols
sumber
1
"Dan bahkan jika itu memang menghasilkan GUID_NULL karena suatu alasan, keunikan akan mengharuskan itu melakukannya hanya sekali! (Jadi Anda harus mencoba untuk memaksa bug ini terjadi dalam pengujian, dan kemudian Anda dapat yakin bahwa itu tidak akan pernah terjadi dalam produksi. ) "- Bagus!
razethestray
3
@razethestray - Anda dapat bertaruh semua yang Anda inginkan di kasino saya.
JeffO
10
@ Jeff Jokes pada Anda, dia memastikan berputar 37 kali di rumah dan akan meletakkan semua uangnya pada yang tidak muncul.
Random832
Pada xamarin, Guid.NewGuid kadang-kadang gagal dan kembali kosong terus-menerus (ketika panduan ditugaskan secara otomatis di ef core) belum dapat menemukan alasannya
Karan Harsh Wardhan
@KaranHarshWardhan Saya harap Anda melaporkannya sebagai bug. :)
Curt Nichols
43

Jika Anda menemukan Guid.NewGuid() == Guid.EmptyAnda telah memenangkan lotere paling sulit di dunia. Jangan repot-repot dengan keunikan atau pemeriksaan tabrakan. Tidak harus melakukan itu adalah apa guids yang untuk . Saya akan menghindarkan Anda dari matematika, ada di mana-mana di web.

Juga, Windows guids selalu memiliki satu "angka" sama dengan 4. Ada beberapa struktur untuk panduan.

Cuplikan kode yang Anda poskan tampak seperti salah satu dev lupa untuk menginisialisasi Guidvariabel dan menemukannya Guid.Empty. Dia keliru diidentifikasi Guid.NewGuid()sebagai penyebabnya. Sekarang dia akan selamanya percaya takhayul akan hal ini.

Bagaimanapun, ini adalah pertanyaan yang salah untuk ditanyakan. Saya yakin kode Anda tidak hanya bergantung pada tidak pernah menggambar Guid.Emptytetapi juga pada keunikan. Itu whileloop tidak menegakkan keunikan. Panduan ada untuk menghasilkan nilai unik tanpa koordinasi. Itu adalah kasus penggunaan mereka.

usr
sumber
5
+1 ke "pertanyaan yang salah untuk ditanyakan". Ini semua tentang keunikan, itu yang paling penting.
Thomas Stringer
1
@rjzii pertimbangkan untuk menjadikan ini jawaban yang diterima!
emcor
18

Lihatlah kode sumber Guid.NewGuidmetode :

public static Guid NewGuid() {
    Contract.Ensures(Contract.Result<Guid>() != Guid.Empty);
    ...
}

Lihat kontrak kode? The Guid.NewGuidMetode tidak pernah memberikan GUID kosong.

sschoof
sumber
2
Tidak yakin mengapa Anda menerima downvote, karena menyebutkan sesuatu yang tidak ada pada jawaban lain. Kehadiran kontrak kode adalah jaminan yang cukup bagus, dan juga memberikan jawaban yang sangat baik untuk pertanyaan awal. +1 untuk gagasan melihat implementasi yang sebenarnya.
Arseni Mourzenko
Saya suka kontrak kode.
Andy
10

Jika Anda akan memeriksa GUID terhadap nol GUID, Anda dengan logika yang sama juga perlu melakukan uji tuntas memeriksa semua GUID lain dalam aplikasi Anda (karena kemungkinan mendapatkan nol harus sama dengan probabilitas mendapatkan GUID lain di aplikasi Anda *). Anda perlu melakukan ini untuk membuktikan aksioma yang Anda lakukan adalah bahwa GUID ini akan unik (yang sebenarnya merupakan aksioma yang sama dengan pengujian vs 0).

Jelas melakukan ini tidak masuk akal.

TLDR; Jika Anda bisa mempercayai NewGuid () untuk menghasilkan hasil yang unik, Anda juga bisa mempercayai itu untuk tidak menghasilkan satu pun GUID yang dikenal.

* Ini sebenarnya bukan probabilitas yang sama dengan. GUID NET selalu sesuai dengan yang berikut ini {________-____-4___-____-____________}sehingga NewGuid TIDAK AKAN PERNAH menghasilkan pedoman nol

Hanya untuk bersenang-senang saya menyarankan perbaikan pada dokumen di sini: http://feedback.msdn.com/forums/257782-msdn-feature-suggestions/suggestions/7143498-fix-documentation-for-newguid

Tidak dicintai, bukan rakyat mereka
sumber
3
Mengapa .NET GUIDs selalu menyertakan 4?
Arturo Torres Sánchez
9
@ ArturoTorresSánchez: Untuk jawaban atas pertanyaan Anda dan banyak fakta menyenangkan lainnya tentang GUID, lihat seri artikel saya yang dimulai di sini. ericlippert.com/2012/04/24/guid-guide-part-one Saya perhatikan bahwa Luke sudah ditautkan ke bagian tiga untuk kenyamanan Anda. Jawaban singkat: GUID versi 4 selalu menyertakan 4.
Eric Lippert
@EricLippert ini artikel yang sangat bagus :)
Tidak dicintai Bukan orang-orangnya