Vale a pena verificar se Guid.NewGuid () é Guid.Empty?


28

Em um dos projetos em que estou trabalhando, o seguinte padrão é visto regularmente:

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

Embora eu entenda que um GUID não é garantido como único e, de acordo com a documentação do MSDN, um GUID gerado pode ser zero , essa é uma consideração prática que realmente vale a pena enviar testes de ciclo para ambos no sentido computacional e em termos de tempo do desenvolvedor pensando nisso ?


1
Se você estiver vendo esse padrão repetidamente, talvez um método utilitário esteja em ordem? Repetir trechos de código como esse parece ser um problema maior do que o fato de você estar verificando um caso de borda que nunca acontecerá e poderá não ter importância, mesmo que tenha acontecido.
psr

27
Esse código existe para manter os jacarés afastados. Existem jacarés onde você escreve código? Não? Então, obviamente, funciona!
Eric Lippert

3
Seja qual for o caso, eu faria isso daqui a pouco.
Arturo Torres Sánchez

3
Por que diabos você está convertendo os guias em seqüências de caracteres e comparando? eles comparam bem por conta própria.
Andy

2
A documentação foi atualizada: "É garantido que o Guid retornado não é igual a Guid.Empty."
sschoof

Respostas:


33

Eu sugeriria que não vale a pena procurar por Guid.Empty. Os documentos de Guid.NewGuid, por algum motivo, mencionam que

A chance de o valor do novo Guid ser zero ou igual a qualquer outro Guid é muito baixa.

Guid.NewGuid é um wrapper para a API Win32 CoCreateGuid , que não faz menção ao retorno de todos os zeros.

Raymond Chen vai mais longe , sugerindo que

nenhuma implementação válida de CoCreateGuid pode gerar GUID_NULL

Então, não, eu não me preocuparia com isso. Não vou adivinhar por que os documentos do Guid.NewGuid sequer o mencionam.


1
"E mesmo que ele gerasse GUID_NULL por algum motivo, a exclusividade exigiria isso apenas uma vez! )" - Agradável!
razethestray

3
@razethestray - Você pode apostar tudo o que quiser no meu cassino.
JeffO 25/02

10
@JeffO brinca com você, ele fez questão de girar 37 vezes em casa e vai investir todo o seu dinheiro no que não apareceu.
Random832

No xamarin, o Guid.NewGuid às vezes falha e retorna vazio constantemente (quando o guid é atribuído automaticamente no ef core) não conseguiu descobrir o porquê
Karan Harsh Wardhan

@KaranHarshWardhan Espero que você tenha relatado isso como um bug. :)
Curt Nichols

43

Se você acha Guid.NewGuid() == Guid.Emptyque ganhou a loteria mais difícil do mundo. Não se preocupe com nenhuma verificação de singularidade ou colisão. Não ter que fazer isso é o que guids são para . Vou poupar-lhe a matemática, está em toda parte na web.

Além disso, os guias do Windows sempre têm um "dígito" igual a 4. Existe alguma estrutura para os guias.

Esse snippet de código que você postou parece que um desenvolvedor esqueceu de inicializar uma Guidvariável e achou que era Guid.Empty. Ele erroneamente identificado Guid.NewGuid()como a causa. Agora ele sempre acreditará supersticiosamente nisso.

De qualquer forma, esta é a pergunta errada a ser feita. Tenho certeza de que seu código não depende apenas do desenho, Guid.Emptymas também da exclusividade. Esse whileloop não impõe exclusividade. Os guias estão aí para produzir um valor único sem coordenação. Esse é o caso de uso deles.


5
+1 em "pergunta errada a ser feita". É tudo uma questão de singularidade, é tudo o que realmente importa.
Thomas Stringer

1
@rjzii considere fazer disso a resposta aceita!
emcor 27/02

18

Veja o código fonte do Guid.NewGuidmétodo :

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

Veja o código do contrato? O Guid.NewGuidmétodo nunca fornece um GUID vazio.


2
Não sei por que você recebeu um voto negativo, pois menciona algo que está faltando em outras respostas. A presença do contrato de código é uma garantia muito boa e também fornece uma excelente resposta para a pergunta original. +1 para a ideia de analisar a implementação real.
Arseni Mourzenko

Eu amo contratos de código.
Andy

10

Se você estiver indo para verificar o GUID contra o GUID zero, pela mesma lógica também precisará fazer a devida diligência para compará-lo com todos os outros GUIDs em seu aplicativo (como a probabilidade de obter um zero deve ser a mesma que a probabilidade de obtendo qualquer outro GUID no seu aplicativo *). Você precisa fazer isso para provar que o axioma no qual você está agindo é que esse GUID será único (que na verdade é o mesmo axioma do teste vs 0).

Obviamente, fazer isso é um absurdo.

TLDR; Se você pode confiar em NewGuid () para produzir resultados exclusivos, também pode confiar em não produzir nenhum GUID conhecido único.

* Na verdade, não é a mesma probabilidade que os GUIDs .NET sempre se ajustam ao seguinte, {________-____-4___-____-____________}portanto o NewGuid NUNCA gerará um guia zero

Apenas por diversão, sugeri uma melhoria nos documentos aqui: http://feedback.msdn.com/forums/257782-msdn-feature-suggestions/suggestions/7143498-fix-documentation-for-newguid


3
Por que os GUIDs do .NET sempre incluem um 4?
Arturo Torres Sánchez

9
@ ArturoTorresSánchez: Para obter a resposta à sua pergunta e muitos outros fatos divertidos sobre GUIDs, consulte minha série de artigos que começa aqui. ericlippert.com/2012/04/24/guid-guide-part-one Observo que Luke já está vinculado à parte três para sua conveniência. Resposta curta: Os GUIDs da versão 4 sempre incluem um 4.
Eric Lippert

@EricLippert é um artigo muito bom :)
Não é amado Não é o seu povo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.