25

In one of the projects I'm working on the following pattern is seen on a fairly regular basis:

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

While I understand that a a GUID is not guaranteed to be unique and as per the MSDN documentation a generated GUID may be zero, is this a practical consideration actually worth sending cycles testing for both in the computational sense and in terms of developer time thinking about it?

  • 1
    If you are seeing this pattern repeatedly perhaps a utility method would be in order? Repeating code chunks like this seems like a bigger problem than the fact that you are checking an edge case that will never happen and might not matter even if it did happen. – psr Feb 25 '15 at 21:37
  • 27
    That code is there to keep the alligators away. Are there alligators where you write code? No? Then obviously it works! – Eric Lippert Feb 25 '15 at 22:54
  • 3
    Whatever the case, I would do this in a do-while. – Arturo Torres Sánchez Feb 26 '15 at 2:09
  • 3
    Why on earth are you converting the guids to strings and then comparing? they compare fine on their own. – Andy Mar 2 '15 at 23:56
  • 2
    The documentation had been updated: "The returned Guid is guaranteed to not equal Guid.Empty." – sschoof Nov 12 '15 at 10:35
30

I would suggest it's not worth checking for Guid.Empty. The docs for Guid.NewGuid for some reason mention that

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

Guid.NewGuid is a wrapper for the Win32 API CoCreateGuid, which makes no mention of returning all zeroes.

Raymond Chen goes further, suggesting that

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

So, no, I wouldn't worry about it. I wont' guess as to why the Guid.NewGuid docs even mention it.

  • 1
    "And even if it did generate GUID_NULL for some reason, uniqueness would require that it do so only once! (So you should try to force this bug to occur in test, and then you can be confident that it will never occur in production.)" - Nice! – razethestray Feb 25 '15 at 20:10
  • 3
    @razethestray - You can bet all you want at my casino. – JeffO Feb 25 '15 at 20:14
  • 10
    @JeffO Jokes on you, he made sure to spin 37 times at home and is going to put all his money on the one that didn't come up. – Random832 Feb 25 '15 at 22:16
  • On xamarin, Guid.NewGuid fails sometimes and returns empty constantly(when guid is assigned automatically in ef core) haven't been able to figure out why – Karan Harsh Wardhan 6 hours ago
41

If you find Guid.NewGuid() == Guid.Empty you have won the hardest lottery on earth. Don't bother with any uniqueness or collision checking. Not having to do that is what guids are for. I will spare you the math, it's everywhere on the web.

Also, Windows guids always have one "digit" equal to 4. There is some structure to guids.

That code snippet you posted looks like one dev forgot to initialize a Guid variable and found it to be Guid.Empty. He mistakenly identified Guid.NewGuid() as the cause. Now he will forever superstitiously believe in this.

In any case this is the wrong question to ask. I'm sure your code does not only depend on not ever drawing Guid.Empty but also on uniqueness. That while loop does not enforce uniqueness. Guids are there to produce a unique value without coordination. That is their use case.

  • 5
    +1 to "wrong question to ask". It's all about uniqueness, that's all that really matters. – Thomas Stringer Feb 25 '15 at 22:48
  • 1
    @rjzii consider making this the accepted answer! – emcor Feb 27 '15 at 9:15
15

Look at the source code of Guid.NewGuid method:

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

See the code contract? The Guid.NewGuid method never gives an empty GUID.

  • 2
    Not sure why you received a downvote, since it mentions something which is missing in other answers. The presence of the code contract is a pretty good guarantee, and also gives an excellent answer to the original question. +1 for the idea of looking at the actual implementation. – Arseni Mourzenko Mar 2 '15 at 20:32
  • I love code contracts. – Andy Mar 2 '15 at 23:59
10

If you are going to check the GUID against the zero GUID, you by the same logic also need to do due diligence of checking it against all other GUIDs in your application (as the probability of getting a zero should be the same as the probability of getting any other GUID in your app*). You need to do this to prove the axiom you are acting under is that this GUID will be unique (which is actually the same axiom as testing vs 0).

Obviously doing this is absurd.

TLDR; If you can trust NewGuid() to produce unique results, you can also trust it to not produce any single known GUID.

* Its actually not the same probability as .NET GUIDs always fit the following {________-____-4___-____-____________} so NewGuid will NEVER generate a zero guid

Just for fun I suggested an improvement to the docs here: http://feedback.msdn.com/forums/257782-msdn-feature-suggestions/suggestions/7143498-fix-documentation-for-newguid

  • 3
    Why do .NET GUIDs always include a 4? – Arturo Torres Sánchez Feb 26 '15 at 2:19
  • 8
    @ArturoTorresSánchez: For the answer to your question and many more fun facts about GUIDs, see my series of articles which begins here. ericlippert.com/2012/04/24/guid-guide-part-one I note that Luke already linked to part three for your convenience. Short answer: Version 4 GUIDs always include a 4. – Eric Lippert Feb 26 '15 at 2:34
  • @EricLippert its a very good article :) – Luke McGregor Feb 26 '15 at 3:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.