Czy warto nawet sprawdzić, czy Guid.NewGuid () to Guid.Empty?

28

W jednym z projektów pracuję nad następującym schematem, który pojawia się dość regularnie:

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

Chociaż rozumiem, że aa GUID nie jest gwarantowana być unikalny i zgodnie z dokumentacji MSDN generowane GUID może być zerowy , jest to praktyczny wzajemne rzeczywiście warto wysyłania cykle testowe zarówno w obliczeniowej sensie i pod względem czasu deweloper o tym myśleć ?

rjzii
źródło
1
Jeśli często widzisz ten wzorzec, być może przydałaby się metoda użyteczności? Powtarzanie takich fragmentów kodu wydaje się większym problemem niż fakt, że sprawdzasz przypadek krawędzi, który nigdy się nie wydarzy i może nie mieć znaczenia, nawet jeśli tak się stanie.
psr
27
Ten kod ma na celu powstrzymanie aligatorów. Czy są aligatory, w których piszesz kod? Nie? To oczywiście działa!
Eric Lippert,
3
W każdym razie zrobiłbym to od razu.
Arturo Torres Sánchez
3
Dlaczego, u licha, konwertujecie prowadnice na łańcuchy, a następnie porównacie? same sobie dobrze porównują.
Andy
2
Dokumentacja została zaktualizowana: „Zwracany Guid nie gwarantuje równego Guid.Empty”.
sschoof

Odpowiedzi:

33

Sugerowałbym, że nie warto sprawdzać Guid.Empty. Dokumenty Guid.NewGuid z jakiegoś powodu wspominają o tym

Szansa, że ​​wartość nowego Guida będzie równa zeru lub równa dowolnemu innemu Guidowi, jest bardzo niska.

Guid.NewGuid to opakowanie dla interfejsu API CoCreateGuid interfejsu API Win32 , w którym nie ma wzmianki o zwracaniu wszystkich zer.

Raymond Chen idzie dalej , sugerując to

żadna poprawna implementacja CoCreateGuid nie może wygenerować GUID_NULL

Więc nie, nie martwiłbym się tym. Nie zgaduję, dlaczego doktorzy Guid.NewGuid nawet o tym wspominają.

Curt Nichols
źródło
1
„I nawet jeśli z jakiegoś powodu wygenerował GUID_NULL, wyjątkowość wymagałaby, aby zrobić to tylko raz! (Więc powinieneś spróbować zmusić ten błąd do wystąpienia w teście, a wtedy możesz być pewien, że nigdy nie wystąpi on w produkcji. )" - Miły!
razethestray
3
@razethestray - Możesz postawić wszystko, co chcesz w moim kasynie.
JeffO,
10
@JeffO żartuje z ciebie, upewnił się, że zakręcił 37 razy w domu i zamierza położyć wszystkie swoje pieniądze na tym, który nie przyszedł.
Random832,
Na Xamarinie Guid.NewGuid czasami zawiesza się i zwraca stale puste (gdy GUID jest przypisywany automatycznie w rdzeniu ef) nie był w stanie dowiedzieć się, dlaczego
Karan Harsh Wardhan
@KaranHarshWardhan Mam nadzieję, że zgłosiłeś to jako błąd. :)
Curt Nichols
43

Jeśli okaże się Guid.NewGuid() == Guid.Empty, że wygrałeś najtrudniejszą loterię na ziemi. Nie zawracaj sobie głowy sprawdzaniem unikatowości i kolizji. Nie mając na to jest to, co GUID są za . Oszczędzę ci matematyki, jest wszędzie w sieci.

Ponadto prowadnice systemu Windows zawsze mają jedną „cyfrę” równą 4. Przewodniki mają pewną strukturę.

Ten fragment kodu, który opublikowałeś, wygląda na to, że jeden programista zapomniał zainicjować Guidzmienną i stwierdził, że tak jest Guid.Empty. Pomyłkowo zidentyfikował Guid.NewGuid()jako przyczynę. Teraz na zawsze zabobonnie w to uwierzy.

W każdym razie jest to niewłaściwe pytanie. Jestem pewien, że Twój kod nie zależy nie tylko od rysowania, Guid.Emptyale także od wyjątkowości. Ta whilepętla nie wymusza wyjątkowości. Przewodniki mają zapewnić wyjątkową wartość bez koordynacji. To jest ich przypadek użycia.

usr
źródło
5
+1 do „niewłaściwego pytania, które należy zadać”. Chodzi o wyjątkowość, to wszystko, co naprawdę się liczy.
Thomas Stringer,
1
@ rjzii zastanów się, czy to zaakceptowana odpowiedź!
emcor
18

Spójrz na kod źródłowy Guid.NewGuidmetody :

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

Widzisz umowę kodową? Guid.NewGuidMetoda nie daje pusty GUID.

sschoof
źródło
2
Nie jestem pewien, dlaczego otrzymałeś opinię negatywną, ponieważ wspomina o czymś, czego brakuje w innych odpowiedziach. Obecność umowy na kod jest dość dobrą gwarancją, a także daje doskonałą odpowiedź na pierwotne pytanie. +1 za pomysł spojrzenia na faktyczną implementację.
Arseni Mourzenko
Uwielbiam umowy kodowe.
Andy
10

Jeśli zamierzasz sprawdzić identyfikator GUID z zerowym identyfikatorem GUID, zgodnie z tą samą logiką należy również dołożyć należytej staranności, sprawdzając go względem wszystkich innych identyfikatorów GUID w aplikacji (ponieważ prawdopodobieństwo uzyskania zera powinno być takie samo jak prawdopodobieństwo uzyskiwanie dowolnego innego identyfikatora GUID w aplikacji *). Musisz to zrobić, aby udowodnić, że aksjomat, pod którym działasz, jest taki, że ten GUID będzie unikalny (co w rzeczywistości jest tym samym aksjomatem, co testowanie vs 0).

Oczywiście robienie tego jest absurdalne.

TLDR; Jeśli możesz zaufać NewGuid (), aby uzyskać unikalne wyniki, możesz również zaufać, że nie wygeneruje żadnego znanego GUID.

* Jego prawdopodobieństwo nie jest takie samo, jak GUID .NET zawsze pasuje do następujących, {________-____-4___-____-____________}więc NewGuid NIGDY nie wygeneruje guid zero

Dla zabawy zaproponowałem ulepszenie dokumentacji tutaj: http://feedback.msdn.com/forums/257782-msdn-feature-suggestions/suggestions/7143498-fix-documentation-for-newguid

Nie kochany Nie ich ludzie
źródło
3
Dlaczego GUI .NET zawsze zawierają 4?
Arturo Torres Sánchez
9
@ ArturoTorresSánchez: Aby uzyskać odpowiedź na twoje pytanie i wiele innych ciekawych faktów na temat GUID, zobacz moją serię artykułów, która zaczyna się tutaj. ericlippert.com/2012/04/24/guid-guide-part-one Zauważam, że Luke już dla twojej wygody nawiązał do trzeciej części. Krótka odpowiedź: GUID wersji 4 zawsze zawierają 4.
Eric Lippert
@EricLippert to bardzo dobry artykuł :)
Nie kochany Nie ich ludzie