Vaut-il même la peine de vérifier si Guid.NewGuid () est Guid.Empty?

28

Dans l'un des projets sur lesquels je travaille, le schéma suivant est observé assez régulièrement:

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

Bien que je comprenne qu'un aa GUID n'est pas garanti d'être unique et que, selon la documentation MSDN, un GUID généré peut être nul , est-ce une considération pratique qui vaut vraiment la peine d'envoyer des tests de cycles à la fois dans le sens du calcul et en termes de temps de développement pour les développeurs ?

rjzii
la source
1
Si vous voyez ce modèle à plusieurs reprises, peut-être qu'une méthode d'utilité serait en règle? La répétition de morceaux de code comme celui-ci semble être un problème plus important que le fait que vous vérifiez un cas de bord qui ne se produira jamais et pourrait ne pas avoir d'importance même si cela s'est produit.
psr
27
Ce code est là pour éloigner les alligators. Y a-t-il des alligators où vous écrivez du code? Non? Alors évidemment ça marche!
Eric Lippert
3
Quoi qu'il en soit, je le ferais en un rien de temps.
Arturo Torres Sánchez
3
Pourquoi diable convertissez-vous les guids en chaînes et comparez-vous ensuite? ils se comparent bien par eux-mêmes.
Andy
2
La documentation a été mise à jour: "Le Guid retourné est garanti différent de Guid.Empty."
sschoof

Réponses:

33

Je dirais que cela ne vaut pas la peine de vérifier Guid.Empty. Les documents pour Guid.NewGuid pour une raison quelconque mentionnent que

La probabilité que la valeur du nouveau Guid soit entièrement nulle ou égale à tout autre Guid est très faible.

Guid.NewGuid est un wrapper pour l'API Win32 CoCreateGuid , qui ne fait aucune mention du retour de tous les zéros.

Raymond Chen va plus loin , suggérant que

aucune implémentation valide de CoCreateGuid ne peut générer GUID_NULL

Donc, non, je ne m'en inquiéterais pas. Je ne devine pas pourquoi les documents Guid.NewGuid le mentionnent même.

Curt Nichols
la source
1
"Et même s'il a généré GUID_NULL pour une raison quelconque, l'unicité exigerait qu'il ne le fasse qu'une fois! )" - Agréable!
razethestray
3
@razethestray - Vous pouvez parier tout ce que vous voulez sur mon casino.
JeffO
10
@JeffO Blagues sur vous, il s'est assuré de tourner 37 fois à la maison et va mettre tout son argent sur celui qui n'est pas venu.
Random832
Sur xamarin, Guid.NewGuid échoue parfois et revient vide en permanence (lorsque guid est affecté automatiquement dans le noyau ef) n'ont pas pu comprendre pourquoi
Karan Harsh Wardhan
@KaranHarshWardhan J'espère que vous avez signalé cela comme un bug. :)
Curt Nichols
43

Si vous trouvez que Guid.NewGuid() == Guid.Emptyvous avez gagné la loterie la plus difficile au monde. Ne vous embêtez pas avec l'unicité ou la vérification des collisions. Ne pas avoir à faire est ce que GUIDs sont pour . Je vais vous épargner les maths, c'est partout sur le web.

De plus, les guides Windows ont toujours un "chiffre" égal à 4. Les guides sont structurés.

L'extrait de code que vous avez publié ressemble à un développeur qui a oublié d'initialiser une Guidvariable et l'a trouvée Guid.Empty. Il a identifié à tort Guid.NewGuid()que la cause. Maintenant, il y croira à jamais superstitieusement.

En tout cas, ce n'est pas la bonne question à poser. Je suis sûr que votre code ne dépend pas seulement de ne jamais dessiner Guid.Emptymais aussi de l'unicité. Cette whileboucle n'impose pas l'unicité. Les guides sont là pour produire une valeur unique sans coordination. C'est leur cas d'utilisation.

usr
la source
5
+1 à "mauvaise question à poser". Tout est question d'unicité, c'est tout ce qui compte vraiment.
Thomas Stringer
1
@rjzii envisagez d'en faire la réponse acceptée!
emcor
18

Regardez le code source de la Guid.NewGuidméthode :

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

Voir le contrat de code? La Guid.NewGuidméthode ne donne jamais un GUID vide.

sschoof
la source
2
Je ne sais pas pourquoi vous avez reçu un downvote, car il mentionne quelque chose qui manque dans les autres réponses. La présence du contrat de code est une assez bonne garantie, et donne également une excellente réponse à la question d'origine. +1 pour l'idée de regarder la mise en œuvre réelle.
Arseni Mourzenko
J'adore les contrats de code.
Andy
10

Si vous allez vérifier le GUID par rapport au GUID zéro, vous devez également, par la même logique, faire preuve de diligence raisonnable en le comparant à tous les autres GUID de votre application (car la probabilité d'obtenir un zéro devrait être la même que la probabilité de obtenir tout autre GUID dans votre application *). Vous devez le faire pour prouver que l'axiome sous lequel vous agissez est que ce GUID sera unique (qui est en fait le même axiome que le test vs 0).

Évidemment, cela est absurde.

TLDR; Si vous pouvez faire confiance à NewGuid () pour produire des résultats uniques, vous pouvez également lui faire confiance pour ne produire aucun GUID connu unique.

* Ce n'est en fait pas la même probabilité que les GUID .NET correspondent toujours aux éléments suivants, {________-____-4___-____-____________}donc NewGuid ne générera JAMAIS un guid zéro

Juste pour le plaisir, j'ai suggéré une amélioration des documents ici: http://feedback.msdn.com/forums/257782-msdn-feature-suggestions/suggestions/7143498-fix-documentation-for-newguid

Pas aimé Pas son peuple
la source
3
Pourquoi les GUID .NET incluent-ils toujours un 4?
Arturo Torres Sánchez
9
@ ArturoTorresSánchez: Pour la réponse à votre question et bien d'autres faits amusants sur les GUID, consultez ma série d'articles qui commence ici. ericlippert.com/2012/04/24/guid-guide-part-one Je note que Luke est déjà lié à la troisième partie pour votre commodité. Réponse courte: les GUID de la version 4 incluent toujours un 4.
Eric Lippert
@EricLippert c'est un très bon article :)
Pas aimé Pas leur peuple