28

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?

rjzii
  • 11,274
  • 6
  • 46
  • 71
  • 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
  • possible duplicate of [Is checking return values always required?](http://programmers.stackexchange.com/questions/267305/is-checking-return-values-always-required) – gnat Feb 25 '15 at 21:37
  • 31
    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
  • 5
    Whatever the case, I would do this in a do-while. – Arturo Torres Sánchez Feb 26 '15 at 02:09
  • an excellent example of [programming by coincidence](https://pragprog.com/the-pragmatic-programmer/extracts/coincidence). – zzzzBov Feb 26 '15 at 16:21
  • 3
    Why on earth are you converting the guids to strings and then comparing? they compare fine on their own. – Andy Mar 02 '15 at 23:56
  • 1
    @Andy Because I didn't write the code myself and just copy-pasted the pattern as an example? – rjzii Mar 03 '15 at 02:42
  • 1
    @rjzii Its still code you're working on, and if ever saw that I'd immediately remove the .ToString() calls. – Andy Mar 03 '15 at 14:58
  • 4
    The [documentation](https://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx) had been updated: "The returned Guid is guaranteed to not equal Guid.Empty." – sschoof Nov 12 '15 at 10:35
  • +1 @sschoof thanks for posting that link. – William Martens Nov 27 '22 at 10:27

5 Answers5

45

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.

usr
  • 2,734
  • 18
  • 15
34

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.

Glorfindel
  • 3,137
  • 6
  • 25
  • 33
Curt Nichols
  • 456
  • 4
  • 4
  • 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 Apr 22 '19 at 05:12
  • @KaranHarshWardhan I'm hoping you reported that as a bug. :) – Curt Nichols Apr 22 '19 at 20:22
  • 1
    @CurtNichols if i reported every bug i got in xamarin, i wouldn't ever get any work done lol. also ef core team has said xamarin compatibility isn't a focus for them so any bugs reported get assigned to "some day". if you saw how migrations need to be done currently you'd laugh – Karan Harsh Wardhan Apr 23 '19 at 06:30
  • @KaranHarshWardhan Which suggests that perhaps whoever wrote this code is aware of the Xamarin bug. – Loren Pechtel Nov 29 '22 at 04:48
  • @LorenPechtel it still exists so i doubt it – Karan Harsh Wardhan Dec 04 '22 at 03:59
21

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.

Arseni Mourzenko
  • 134,780
  • 31
  • 343
  • 513
sschoof
  • 311
  • 1
  • 4
  • 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 02 '15 at 20:32
  • I love code contracts. – Andy Mar 02 '15 at 23:59
  • I'm quite sure that method is not available on iOS, so it's rather pointless. – gnasher729 Nov 28 '22 at 09:34
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

undefined
  • 201
  • 1
  • 5
  • 3
    Why do .NET GUIDs always include a 4? – Arturo Torres Sánchez Feb 26 '15 at 02:19
  • 10
    @ArturoTorresSánchez: For the answer to your question and many more fun facts about GUIDs, see my series of articles which begins here. http://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 02:34
  • @EricLippert its a very good article :) – undefined Feb 26 '15 at 03:00
-1

During development, you might want to check, because there might be situations where a bug in your own code stores a null GUID where it shouldn’t.

After that: A GUID generator might guarantee never to create a null GUID. Or it might generate one randomly - the chance of that is less than one in a billion billion billion billions. In other words it will never happen. (In a galaxy far far away someone posted the same and was wrong).

If the GUID generator is so non-random that it generates empty GUIDs then it will produce so many conflicting GUIDs that you notice.

gnasher729
  • 42,090
  • 4
  • 59
  • 119
  • 1
    Per [another answer](https://softwareengineering.stackexchange.com/a/274978/2471) the contract ensures that `null` will not be returned. – rjzii Nov 28 '22 at 18:07