Vale la pena anche verificare se Guid.NewGuid () è Guid.Empty?


28

In uno dei progetti che sto lavorando, il seguente schema è visto su una base abbastanza regolare:

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

Mentre capisco che un GUID non è garantito per essere unico e secondo la documentazione MSDN un GUID generato può essere zero , è davvero una considerazione pratica che vale la pena inviare cicli di test sia in senso computazionale che in termini di tempo dello sviluppatore a pensarci ?


1
Se vedi ripetutamente questo schema, forse un metodo di utilità sarebbe in ordine? Ripetere blocchi di codice come questo sembra un problema più grande del fatto che stai controllando un caso limite che non accadrà mai e potrebbe non avere importanza anche se fosse successo.
psr

27
Quel codice è lì per tenere lontani gli alligatori. Ci sono alligatori in cui scrivi il codice? No? Quindi ovviamente funziona!
Eric Lippert,

3
In ogni caso, lo farei in un attimo.
Arturo Torres Sánchez,

3
Perché mai stai convertendo le guide in stringhe e poi confrontando? si confrontano bene da soli.
Andy,

2
La documentazione era stata aggiornata: "La guida restituita è garantita non uguale a Guid.Empty."
sschoof,

Risposte:


33

Suggerirei che non vale la pena controllare per Guid.Empty. I documenti per Guid.NewGuid per qualche motivo lo menzionano

La possibilità che il valore del nuovo Guid sia pari a zero o uguale a qualsiasi altro Guid è molto bassa.

Guid.NewGuid è un wrapper per l'API Win32 CoCreateGuid , che non menziona la restituzione di tutti gli zero.

Raymond Chen va oltre , suggerendolo

nessuna implementazione valida di CoCreateGuid può generare GUID_NULL

Quindi no, non me ne preoccuperei. Non indovinerò perché i documenti Guid.NewGuid lo menzionino.


1
"E anche se ha generato GUID_NULL per qualche motivo, l'unicità richiederebbe che lo faccia solo una volta! (Quindi dovresti provare a forzare questo bug nel test, e quindi puoi essere sicuro che non si verificherà mai in produzione. )" - Bello!
razethestray,

3
@razethestray - Puoi scommettere tutto quello che vuoi nel mio casinò.
JeffO,

10
@JeffO Scherzi su di te, si è assicurato di girare 37 volte a casa e metterà tutti i suoi soldi su quello che non è venuto fuori.
Casuale 832,

Su xamarin, Guid.NewGuid a volte fallisce e ritorna costantemente vuoto (quando guid è assegnato automaticamente in ef core) non è stato in grado di capire perché
Karan Harsh Wardhan il

@KaranHarshWardhan Spero che tu l'abbia segnalato come un bug. :)
Curt Nichols il

43

Se scopri Guid.NewGuid() == Guid.Emptydi aver vinto la lotteria più dura della terra. Non preoccuparti di alcuna unicità o controllo delle collisioni. Non avendo a che fare questo è ciò che GUID sono per . Ti risparmierò la matematica, è ovunque sul web.

Inoltre, le guide di Windows hanno sempre una "cifra" uguale a 4. C'è una struttura per le guide.

Quel frammento di codice che hai pubblicato sembra che uno sviluppatore abbia dimenticato di inizializzare una Guidvariabile e l'ha trovata Guid.Empty. Ha erroneamente identificato Guid.NewGuid()come causa. Ora crederà per sempre in modo superstizioso in questo.

In ogni caso questa è la domanda sbagliata da porre. Sono sicuro che il tuo codice non dipende solo dal disegno, Guid.Emptyma anche dall'unicità. Quel whileciclo non impone l'unicità. Le guide sono lì per produrre un valore unico senza coordinamento. Questo è il loro caso d'uso.


5
+1 alla "domanda sbagliata da porre". Si tratta di unicità, questo è tutto ciò che conta davvero.
Thomas Stringer,

1
@rjzii considera l'idea di rendere questa la risposta accettata!
emcor,

18

Guarda il codice sorgente del Guid.NewGuidmetodo :

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

Vedi il contratto in codice? Il Guid.NewGuidmetodo non fornisce mai un GUID vuoto.


2
Non sono sicuro del motivo per cui hai ricevuto un voto negativo, poiché menziona qualcosa che manca in altre risposte. La presenza del contratto in codice è una garanzia abbastanza buona e fornisce anche un'ottima risposta alla domanda originale. +1 per l'idea di guardare l'implementazione effettiva.
Arseni Mourzenko,

Adoro i contratti di codice.
Andy,

10

Se si intende verificare il GUID rispetto al GUID zero, è necessario che, con la stessa logica, si faccia la dovuta diligenza per verificarlo con tutti gli altri GUID dell'applicazione (poiché la probabilità di ottenere uno zero dovrebbe essere uguale alla probabilità di ottenere qualsiasi altro GUID nella tua app *). Devi fare questo per dimostrare che l'assioma con cui stai agendo è che questo GUID sarà unico (che in realtà è lo stesso assioma del test contro 0).

Ovviamente farlo è assurdo.

TLDR; Se puoi fidarti di NewGuid () per produrre risultati unici, puoi anche fidarti che non produca alcun singolo GUID noto.

* In realtà non è la stessa probabilità che i GUID .NET corrispondano sempre a quanto segue, {________-____-4___-____-____________}quindi NewGuid non genererà MAI uno zero guida

Solo per divertimento, ho suggerito un miglioramento dei documenti qui: http://feedback.msdn.com/forums/257782-msdn-feature-suggestions/suggestions/7143498-fix-documentation-for-newguid


3
Perché i GUID .NET includono sempre un 4?
Arturo Torres Sánchez,

9
@ ArturoTorresSánchez: per la risposta alla tua domanda e molti altri fatti divertenti sui GUID, vedi la mia serie di articoli che inizia qui. ericlippert.com/2012/04/24/guid-guide-part-one Prendo atto che Luke si è già collegato alla terza parte per comodità. Risposta breve: I GUID versione 4 includono sempre un 4.
Eric Lippert,

@EricLippert è un ottimo articolo :)
Non amato Non è la loro gente il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.