¿Vale la pena verificar si Guid.NewGuid () es Guid.Empty?

28

En uno de los proyectos en los que estoy trabajando, el siguiente patrón se ve con bastante regularidad:

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

Si bien entiendo que no se garantiza que un GUID sea ​​único y, según la documentación de MSDN, un GUID generado puede ser cero , es una consideración práctica que realmente vale la pena enviar pruebas de ciclos tanto en el sentido computacional como en términos de tiempo del desarrollador pensando en ello ?

rjzii
fuente
1
Si está viendo este patrón repetidamente, ¿tal vez un método de utilidad estaría en orden? La repetición de fragmentos de código como este parece ser un problema mayor que el hecho de que esté verificando un caso límite que nunca sucederá y que podría no importar incluso si sucediera.
PSR
27
Ese código está ahí para mantener alejados a los caimanes. ¿Hay caimanes donde escribes código? ¿No? ¡Entonces obviamente funciona!
Eric Lippert
3
Cualquiera sea el caso, lo haría en un momento.
Arturo Torres Sánchez
3
¿Por qué demonios estás convirtiendo las guías en cadenas y luego comparando? se comparan bien solos.
Andy
2
La documentación se había actualizado: "Se garantiza que el Guid devuelto no es igual a Guid.Empty".
sschoof

Respuestas:

33

Sugeriría que no vale la pena buscar Guid.Empty. Los documentos de Guid.NewGuid por alguna razón mencionan que

La posibilidad de que el valor del nuevo Guid sea cero o igual a cualquier otro Guid es muy baja.

Guid.NewGuid es un contenedor para Win32 API CoCreateGuid , que no menciona la devolución de todos los ceros.

Raymond Chen va más allá , sugiriendo que

ninguna implementación válida de CoCreateGuid puede generar GUID_NULL

Entonces, no, no me preocuparía por eso. No adivinaré por qué los documentos Guid.NewGuid incluso lo mencionan.

Curt Nichols
fuente
1
"¡E incluso si generó GUID_NULL por alguna razón, la unicidad requeriría que lo haga solo una vez! (Por lo tanto, debe intentar forzar este error para que ocurra en la prueba, y luego puede estar seguro de que nunca ocurrirá en la producción. )" - ¡Agradable!
razethestray
3
@razethestray - Puedes apostar todo lo que quieras en mi casino.
JeffO
10
@JeffO bromea contigo, se aseguró de girar 37 veces en casa y va a poner todo su dinero en el que no salió.
Random832
En xamarin, Guid.NewGuid falla a veces y regresa vacío constantemente (cuando guid se asigna automáticamente en ef core) no ha podido entender por qué
Karan Harsh Wardhan
@KaranHarshWardhan Espero que hayas reportado eso como un error. :)
Curt Nichols
43

Si descubres Guid.NewGuid() == Guid.Emptyque has ganado la lotería más dura del mundo. No te molestes con ninguna singularidad o comprobación de colisión. No tener que hacer eso es lo GUID son para . Te ahorraré las matemáticas, está en todas partes en la web.

Además, las guías de Windows siempre tienen un "dígito" igual a 4. Hay alguna estructura para los guías.

El fragmento de código que publicó parece que un desarrollador olvidó inicializar una Guidvariable y descubrió que era Guid.Empty. Se identificó erróneamente Guid.NewGuid()como la causa. Ahora él siempre creerá supersticiosamente en esto.

En cualquier caso, esta es una pregunta incorrecta. Estoy seguro de que su código no solo depende de no dibujar nunca, Guid.Emptysino también de su singularidad. Ese whileciclo no impone la unicidad. Las guías están ahí para producir un valor único sin coordinación. Ese es su caso de uso.

usr
fuente
55
+1 a "pregunta incorrecta que hacer". Se trata de singularidad, eso es todo lo que realmente importa.
Thomas Stringer
1
¡@rjzii considera hacer de esto la respuesta aceptada!
emcor
18

Mira el código fuente del Guid.NewGuidmétodo :

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

Ver el código del contrato? El Guid.NewGuidmétodo nunca da un GUID vacío.

sschoof
fuente
2
No estoy seguro de por qué recibió un voto negativo, ya que menciona algo que falta en otras respuestas. La presencia del contrato de código es una garantía bastante buena, y también da una excelente respuesta a la pregunta original. +1 por la idea de mirar la implementación real.
Arseni Mourzenko
Me encantan los contratos de código.
Andy
10

Si va a verificar el GUID contra el GUID cero, por la misma lógica también debe hacer la debida diligencia para verificarlo contra todos los otros GUID en su aplicación (ya que la probabilidad de obtener un cero debe ser la misma que la probabilidad de obtener cualquier otro GUID en su aplicación *). Debe hacer esto para demostrar que el axioma en el que está actuando es que este GUID será único (que en realidad es el mismo axioma que las pruebas vs 0).

Obviamente, hacer esto es absurdo.

TLDR; Si puede confiar en NewGuid () para producir resultados únicos, también puede confiar en que no produzca ningún GUID conocido.

* En realidad, no es la misma probabilidad que los GUID de .NET siempre se ajustan a lo siguiente, {________-____-4___-____-____________}por lo que NewGuid NUNCA generará un GUID cero

Solo por diversión, sugerí una mejora en los documentos aquí: http://feedback.msdn.com/forums/257782-msdn-feature-suggestions/suggestions/7143498-fix-documentation-for-newguid

No amado No es su gente
fuente
3
¿Por qué los GUID de .NET siempre incluyen un 4?
Arturo Torres Sánchez
99
@ ArturoTorresSánchez: Para obtener la respuesta a su pregunta y muchos más datos divertidos sobre los GUID, consulte mi serie de artículos que comienza aquí. ericlippert.com/2012/04/24/guid-guide-part-one Observo que Luke ya se vinculó a la tercera parte para su conveniencia. Respuesta corta: los GUID de la Versión 4 siempre incluyen un 4.
Eric Lippert
@EricLippert es un muy buen artículo :)
No amado No es su gente