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

25

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

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

Pur comprendendo che un GUID non è garantito per essere univoco e secondo la documentazione MSDN un generato GUID può essere zero , è una considerazione pratica che vale la pena inviare cicli di test per entrambi in senso computazionale e in termini di tempo di sviluppo a pensarci?

    
posta rjzii 25.02.2015 - 20:42
fonte

4 risposte

30

Suggerirei che non valga la pena controllare per Guid.Empty. I documenti per Guid.NewGuid per qualche ragione menzionano che

The chance that the value of the new Guid will be all zeros or equal to any other Guid is very low.

Guid.NewGuid è un wrapper per l'API Win32 CoCreateGuid , che non fa menzione di restituire tutti gli zeri.

Raymond Chen va oltre , suggerendo che

no valid implementation of Co­Create­Guid can generate GUID_NULL

Quindi, no, non me ne preoccuperei. Non intendo il motivo per cui i documenti Guid.NewGuid lo menzionino addirittura.

    
risposta data 25.02.2015 - 21:02
fonte
41

Se trovi Guid.NewGuid() == Guid.Empty hai vinto la lotteria più difficile sulla terra. Non preoccuparti di univocità o controllo di collisione. Non doverlo fare è ciò che i guids sono per . Ti risparmierò la matematica, è ovunque sul web.

Inoltre, i guids di Windows hanno sempre una "cifra" uguale a 4 . C'è qualche struttura nei guids.

Lo snippet di codice che hai postato sembra che un dev abbia dimenticato di inizializzare una variabile Guid e ha trovato che è Guid.Empty . Ha identificato erroneamente Guid.NewGuid() come causa. Ora crederà per sempre in superstiziosamente in questo.

In ogni caso questa è la domanda sbagliata da porre. Sono sicuro che il tuo codice non dipende solo dal non disegnare Guid.Empty ma anche dall'unicità. Quel ciclo while non impone l'unicità. I guid sono lì per produrre un valore unico senza coordinamento. Questo è il loro caso d'uso.

    
risposta data 25.02.2015 - 22:07
fonte
15

Guarda il codice sorgente del metodo Guid.NewGuid :

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

Vedi il contratto del codice? Il metodo Guid.NewGuid non fornisce mai un GUID vuoto.

    
risposta data 02.03.2015 - 17:32
fonte
10

Se si intende controllare il GUID rispetto al GUID zero, è anche necessario eseguire la dovuta diligenza per verificarlo rispetto a tutti gli altri GUID dell'applicazione (poiché la probabilità di ottenere uno zero dovrebbe essere la stessa di la probabilità di ottenere qualsiasi altro GUID nella tua app *). Hai bisogno di fare questo per dimostrare che l'assioma che stai facendo è che questo GUID sarà unico (che è in realtà lo stesso assioma del test rispetto a 0).

Ovviamente questo è assurdo.

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

* In realtà non è la stessa probabilità che i GUID .NET si adattino sempre al seguente {________-____-4___-____-____________} , quindi NewGuid non genererà mai un zero guid

Solo per divertimento ho suggerito un miglioramento dei documenti qui: link

    
risposta data 26.02.2015 - 02:11
fonte

Leggi altre domande sui tag