Guid são todos os 0 (zeros)?

241

Estou testando alguns serviços WCF que enviam objetos com Guids para frente e para trás. No código de teste do meu aplicativo da web, estou fazendo o seguinte:

var responseObject = proxy.CallService(new RequestObject
{
    Data = "misc. data",
    Guid = new Guid()
});

Por alguma razão, a chamada para o novo Guid () está gerando Guids com todos os 0 (zeros) como este:

00000000-0000-0000-0000-000000000000

O que poderia estar causando isso?

Didaxis
fonte
9
Após sua edição, essa é uma pergunta totalmente nova. E são necessárias muito mais informações para determinar a nova resposta.
Scott Rippey
3
Removida a parte editada que mudou a pergunta.
Didaxis
115
+1 porque eu usei esta pergunta para roubar um em branco guid uma dúzia de vezes :)
jmosesman
5
@jmosesman, é melhor usar a formaGuid.Empty
Jonathan Moosekian
4
@ JonathanM Na verdade, estou usando em um script SQL. Esta postagem aparece primeiro após a pesquisa.
jmosesman

Respostas:

428

Use o método estático em Guid.NewGuid()vez de chamar o construtor padrão.

var responseObject = proxy.CallService(new RequestObject
{
    Data = "misc. data",
    Guid = Guid.NewGuid()
});
Mark Byers
fonte
18
+1 para a resposta correta, bem como um link para a documentação adequada.
ObscureRobot
109

Lições a aprender com isso:

1) Guid é um tipo de valor, não um tipo de referência.

2) Chamar o construtor padrão new S()em qualquer tipo de valor sempre devolve a forma totalmente zero desse tipo de valor, seja ele qual for. É logicamente o mesmo que default(S).

Eric Lippert
fonte
3
Ele é compilado na mesma IL default(S)ou há alguma sutileza que estou faltando?
Configurator
8
@ configurador: Sim. De fato, a representação interna do compilador de "default (S)" e "new S ()" é a mesma; nós não os distinguimos internamente, o que levou a alguns erros infelizes ao longo dos anos, porque na verdade eles não são totalmente idênticos. Por exemplo, const int x = new int();não deveria ser legal de acordo com as especificações, mas const int x = default(int);é; nós permitimos ambos.
111111 Eric
1
@ configurador - se você estiver interessado em casos de canto relacionados, talvez msmvps.com/blogs/jon_skeet/archive/2008/12/10/… também seja de seu interesse.
Kvb
56

Tente isso:

var responseObject = proxy.CallService(new RequestObject
{
    Data = "misc. data",
    Guid = new Guid.NewGuid()
});

Isso irá gerar um valor Guid 'real'. Quando você cria um tipo de referência, ele fornece o valor padrão (que, neste caso, são todos os zeros para um Guid).

Quando você cria um novo Guid, ele será inicializado com todos os zeros, que é o valor padrão para o Guid. É basicamente o mesmo que criar um "novo" int (que é um tipo de valor, mas você pode fazer isso de qualquer maneira):

Guid g1;                    // g1 is 00000000-0000-0000-0000-000000000000
Guid g2 = new Guid();       // g2 is 00000000-0000-0000-0000-000000000000
Guid g3 = default(Guid);    // g3 is 00000000-0000-0000-0000-000000000000
Guid g4 = Guid.NewGuid();   // g4 is not all zeroes

Compare isso com a mesma coisa com um int:

int i1;                     // i1 is 0
int i2 = new int();         // i2 is 0
int i3 = default(int);      // i3 is 0
JohnD
fonte
1
g1será compilado apenas como campo e não como variável local. Também os índices em sua coluna de comentário não corresponder-se com o mesmo linha do código
CodesInChaos
1
@CodeInChaos: Obrigado, corrigimos os comentários. FYI, a linha g1 faz realmente compilar ...
JohnD
3
Ele será compilado como está, mas não possui valor definido. Se você adicionar um código que o leia (antes de escrever), ele não será mais compilado.
CodesInChaos
1
Certo, bom ponto, você receberá um erro se usar uma variável não inicializada, para que o valor não possa ser usado.
JohnD
1
com voto negativo porque a linha "Guid = Guid.NewGuid ();" pode confundir desenvolvedores mais recentes. Considere editar para algo como "Guid someGuid = Guid.NewGuid ();" como a linha g2;)
daviesdoesit
25

Tente fazer:

Guid foo = Guid.NewGuid();
Dylan Smith
fonte
1
Razão para voto negativo: "Guid" é um tipo, mas é usado como uma variável.
Daviesdoesit
19

Não posso dizer quantas vezes isso ocorreu. mim.

Guid myGuid = Guid.NewGuid(); 
Matt Dawdy
fonte
11

No espírito de estar completo, as respostas que instruem você a usar Guid.NewGuid()estão corretas.

Ao abordar sua edição subsequente, você precisará postar o código da sua RequestObjectturma. Suspeito que sua propriedade guid não esteja marcada como DataMembere, portanto, não esteja sendo serializada por fio. Como default(Guid)é o mesmo que new Guid()(ou seja, todos 0), isso explicaria o comportamento que você está vendo.

Adam Robinson
fonte