Guid è tutti 0 (zeri)?


241

Sto testando alcuni servizi WCF che inviano oggetti con Guide avanti e indietro. Nel mio codice di test dell'app Web, sto eseguendo le seguenti operazioni:

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

Per qualche ragione, la chiamata al nuovo Guid () sta generando Guide con tutti gli 0 (zeri) in questo modo:

00000000-0000-0000-0000-000000000000

Che cosa potrebbe causare questo?


9
Dopo la modifica, questa è una domanda completamente nuova. E sono necessarie molte più informazioni per determinare la nuova risposta.
Scott Rippey,

3
Rimossa la parte modificata che ha cambiato la domanda.
Didaxis,

115
+1 perché ho usato questa domanda per rubare una guida in bianco una dozzina di volte :)
jmosesman,

5
@jmosesman, è meglio usare il moduloGuid.Empty
Jonathan Moosekian il

4
@JonathanM In realtà lo sto usando in uno script SQL. Questo post viene visualizzato per primo dopo la ricerca.
jmosesman,

Risposte:


428

Utilizzare il metodo statico Guid.NewGuid()invece di chiamare il costruttore predefinito.

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

18
+1 per la risposta corretta e un collegamento alla documentazione corretta.
ObscureRobot,

109

Lezioni da imparare da questo:

1) Guid è un tipo di valore, non un tipo di riferimento.

2) Chiamare il costruttore predefinito new S()su qualsiasi tipo di valore ti restituisce sempre la forma zero di quel tipo di valore, qualunque esso sia. È logicamente lo stesso di default(S).


3
Si compila nello stesso IL default(S)o ci sono delle sottigliezze che mi mancano?
configuratore

8
@configurator: lo fa. In effetti, la rappresentazione interna del compilatore di "default (S)" e "new S ()" sono gli stessi; non li distinguiamo internamente, il che ha portato ad alcuni sfortunati bug nel corso degli anni perché in realtà non sono del tutto identici. Ad esempio, const int x = new int();non dovrebbe essere legale secondo le specifiche, ma lo const int x = default(int);è; permettiamo entrambi.
Eric Lippert,

1
@configurator - se sei interessato a casi angolari correlati, forse anche msmvps.com/blogs/jon_skeet/archive/2008/12/10/… sarebbe interessante.
kvb,

56

Prova questo invece:

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

Ciò genererà un valore Guid "reale". Quando nuovi un tipo di riferimento, ti darà il valore predefinito (che in questo caso è tutti zero per un Guid).

Quando si crea un nuovo Guid, questo verrà inizializzato su tutti gli zero, che è il valore predefinito per Guid. Fondamentalmente è lo stesso della creazione di un "nuovo" int (che è un tipo di valore ma puoi farlo comunque):

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

Confronta questo per fare la stessa cosa con un int:

int i1;                     // i1 is 0
int i2 = new int();         // i2 is 0
int i3 = default(int);      // i3 is 0

1
g1verrà compilato solo come campo e non come variabile locale. Anche gli indici nella colonna dei commenti non corrispondono alla stessa riga del codice
CodesInChaos

1
@CodeInChaos: Grazie, risolti i commenti. Cordiali saluti, la linea g1 in realtà si compila ...
JohnD,

3
Si compilerà così com'è, ma non ha alcun valore definito. Se aggiungi il codice che lo legge (prima di scriverlo) non verrà più compilato.
CodesInChaos

1
Bene, buon punto, otterrai un errore se usi una variabile non inizializzata, quindi il valore non può essere usato.
JohnD,

1
sotto votato perché la riga "Guid = Guid.NewGuid ();" potrebbe confondere gli sviluppatori più recenti. Valuta la possibilità di modificare qualcosa come "Guid someGuid = Guid.NewGuid ();" come la linea g2;)
daviesdoesit

25

Prova a fare:

Guid foo = Guid.NewGuid();

1
Motivo del downvote: "Guid" è un tipo ma viene utilizzato come una variabile.
daviesdoesit,

19

Non posso dirti quante volte questo ha catturato. me.

Guid myGuid = Guid.NewGuid(); 

11

Nello spirito di essere completo, le risposte che ti indicano di usare Guid.NewGuid()sono corrette.

Nell'affrontare la modifica successiva, dovrai pubblicare il codice per la tua RequestObjectclasse. Sospetto che la tua proprietà guid non sia contrassegnata come a DataMembere quindi non venga serializzata via cavo. Dato che default(Guid)è uguale a new Guid()(cioè tutti 0), questo spiegherebbe il comportamento che stai vedendo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.