Guid.NewGuid () Guid.Empty olup olmadığını kontrol etmeye bile değer mi?


28

Üzerinde çalıştığım projelerden birinde, aşağıdaki düzen üzerinde oldukça düzenli olarak görülmektedir:

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

Her ne kadar bir GUID'in benzersiz olduğunu garanti etmiyorsam ve MSDN dokümantasyonuna göre üretilen bir GUID'in sıfır olabileceğini anlamış olsam da , bu aslında hem hesaplamalı anlamda hem de onu düşünen geliştirici zamanı açısından test sınamaları göndermeye değer pratik bir düşüncedir. ?


1
Bu deseni tekrar tekrar görüyorsanız, belki de bir yardımcı yöntem sırayla olur mu? Bunun gibi kod parçalarını tekrarlamak, asla gerçekleşmeyecek olan bir olayı kontrol ettiğinizden ve gerçekleşmiş olsa bile fark etmeyeceğinizden daha büyük bir problem gibi görünüyor.
psr

27
Bu kod timsahları uzak tutmak için orada. Kod yazdığınız timsahlar var mı? Yok hayır? O zaman belli ki işe yarıyor!
Eric Lippert

3
Durum ne olursa olsun, bunu bir süre içinde yapardım.
Arturo Torres Sánchez

3
Neden yeryüzünde kılavuzları dizgelere dönüştürüyorsunuz ve sonra karşılaştırıyorsunuz? kendi başlarına para cezası karşılaştırırlar.
Andy

2
Dokümantasyon güncellenen vardı: "döndü Guid eşit değildir Guid.Empty garantilidir."
saat

Yanıtlar:


33

Guid.Empty'yi kontrol etmeye değmez. Bazı nedenlerden dolayı Guid.NewGuid için dokümanlar

Yeni Rehberin değerinin tamamen sıfır olması veya herhangi bir Rehbere eşit olma ihtimali çok düşüktür.

Guid.NewGuid, tüm sıfırları döndürmekten söz etmeyen , Win32 API CoCreateGuid için bir sarıcıdır .

Raymond Chen daha ileri giderek , bunu önerdi

Geçerli bir CoCreateGuid uygulaması GUID_NULL üretemez

Yani, hayır, endişelenmem. Guid.NewGuid doktorlarının neden bahsettiğini bile sanmıyorum.


1
“Ve bir nedenden dolayı GUID_NULL üretmiş olsa bile, benzersizlik bunu sadece bir kez yapmasını gerektirecekti! )" - Güzel!
razethestray

3
@razethestray - Kumarhanemde istediğin kadar bahse girebilirsin.
JeffO

10
@JeffO Sana şaka yapıyor, 37 kez evinde döndüğünden emin oldu ve gelmemiş olana tüm parasını harcayacak.
Random832

Xamarin'de Guid.NewGuid bazen başarısız oluyor ve sürekli boş dönüyor (kılavuz ef çekirdeğinde otomatik olarak atandığında) nedenini
çözemedi

@KaranHarshWardhan Umarım bunu bir hata olarak bildirmişsindir. :)
Curt Nichols

43

Eğer bulursanız Guid.NewGuid() == Guid.Emptysize dünyanın en sert piyango kazandı. Benzersizlik veya çarpışma kontrolü ile uğraşmayın. Bunu yapmak zorunda değilsiniz, rehberler bunun içindir . Sana matematiği ayıracağım, web'de her yerde.

Ayrıca, Windows kılavuzları her zaman eşit bir "rakam" a sahiptir 4. Kılavuzların bir yapısı var.

Gönderdiğiniz kod pasajı, bir Guiddeğişkeni başlatmayı unutmuş ve öyle olduğunu buldu Guid.Empty. Yanlışlıkla Guid.NewGuid()sebep olarak belirlendi . Şimdi sonsuza dek batıl inançlı olarak buna inanacak.

Her durumda bu sorulacak yanlış soru. Kodunuzun yalnızca çizime Guid.Emptydeğil, aynı zamanda benzersiz olmasına da bağlı olduğundan eminim . Bu whiledöngü benzersizliği zorlamaz. Kılavuzlar, koordinasyon olmadan benzersiz bir değer üretmek için varlar . Bu onların kullanım durumu.


5
+1 ila "sormak yanlış soru". Hepsi benzersiz olmakla ilgili, gerçekten önemli olan bu.
Thomas Stringer

1
@ rjzii bunu kabul edilen cevap olarak kabul et!
emcor

18

Yöntemin kaynak kodunaGuid.NewGuid bakın :

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

Kod sözleşmesine bakınız? Bu Guid.NewGuidyöntem hiçbir zaman boş bir GUID vermez.


2
Diğer yanıtlarda eksik olan bir şeyden bahsettiği için neden aşağı oy aldığınızdan emin değilim. Kod sözleşmesinin varlığı oldukça iyi bir garantidir ve ayrıca orijinal soruya mükemmel bir cevap verir. Gerçek uygulamaya bakmak fikri için +1.
Arseni Mourzenko

Kod sözleşmelerini seviyorum.
Andy

10

Eğer GUID’yi sıfır GUID’ye karşı kontrol edecekseniz, aynı mantıkla, başvurunuzdaki diğer tüm GUID’lere karşı kontrol etme gereğini de dikkatlice incelemelisiniz (sıfır alma olasılığı aynı olmalıdır. uygulamanızda başka bir GUID almak *). Bunun altında hareket etmekte olduğunuz aksiyomu kanıtlamak için yapmanız gerekir, bu GUID'in benzersiz olacağıdır (aslında test vs 0 ile aynı aksiyomdur).

Belli ki bunu yapmak çok saçma.

TLDR; Benzersiz sonuçlar üretmek için NewGuid () 'e güvenebilirseniz, bilinen tek bir GUID üretmemesine de güvenebilirsiniz.

* Aslında, her zaman .NET GUID'lerle aynı olasılık değildir; {________-____-4___-____-____________}NewGuid, ASLA sıfır kılavuz üretmez.

Sadece eğlence için burada dokümanlar için bir geliştirme önerdim: http://feedback.msdn.com/forums/257782-msdn-feature-suggestions/suggestions/7143498-fix-documentation-for-newguid


3
Neden .NET GUID'leri her zaman 4 içerir?
Arturo Torres Sánchez

9
@ ArturoTorresSánchez: Sorunuzun cevabı ve GUID'ler hakkında daha birçok eğlenceli gerçek için, burada başlayan yazı dizisine bakın. ericlippert . Kısa cevap: Sürüm 4 GUID'lerinde her zaman 4 bulunur.
Eric Lippert

@EricLippert çok iyi bir makale :)
İnsanları değil
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.