2011-11-01 12 views
173

Sto testando alcuni servizi WCF che inviano gli oggetti con Guids avanti e indietro. Nel mio web codice di prova app, sto facendo le seguenti: GUIDGuid è tutti 0 (zeri)?

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

Per qualche ragione, la chiamata a nuovo GUID() sta generando con tutti i 0 di (zeri) in questo modo:

00000000-0000-0000-0000-000000000000

Cosa potrebbe causare questo?

+8

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

+0

Sovrapposizione: http://stackoverflow.com/q/7972658/60761 –

+2

Rimossa la parte modificata che ha modificato la domanda. – Didaxis

risposta

332

Utilizzare il metodo statico Guid.NewGuid() anziché chiamare il costruttore predefinito.

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

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

17

Prova a fare:

Guid = Guid.NewGuid(); 
16

Non posso dirvi quante volte questo ha catturato. me.

Guid myGuid = Guid.NewGuid(); 
54

Prova a modificare:

Guid = Guid.NewGuid(); 

Questo genererà un valore di 'reale' Guid. Quando aggiungi un nuovo tipo di riferimento, ti darà il valore predefinito (che in questo caso è tutti zero per un Guid).

Quando si crea un nuovo Guid, lo inizializzerà su tutti gli zeri, che è il valore predefinito per Guid. E 'fondamentalmente la stessa come la creazione di un "nuovo" int (che è un tipo di valore, ma si può fare questo in ogni modo):

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 a 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 
+0

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

+0

@CodeInChaos: Grazie, i commenti sono stati corretti. Cordiali saluti, la linea g1 in realtà compila ... – JohnD

+2

Si compilerà come è, ma non ha un valore definito. Se aggiungi il codice che lo legge (prima di scriverlo) non verrà più compilato. – CodesInChaos

99

Lezioni per 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 restituisce sempre la forma tutto-zero di quel tipo di valore, qualunque esso sia. È logicamente lo stesso di default(S).

+1

Si compila nello stesso IL di "default (S)" o ci sono sottigliezze che mi mancano? – configurator

+5

@configurator: lo fa. In effetti, la rappresentazione interna del compilatore di "default (S)" e "new S()" è la stessa; non li distinguiamo internamente, il che ha portato ad alcuni bug infelici nel corso degli anni perché in effetti non sono * abbastanza * identici. Ad esempio, 'const int x = new int();' non dovrebbe essere legale secondo le specifiche, ma 'const int x = default (int);' is; permettiamo entrambi. –

+0

@configurator - se sei interessato a casi d'angolo correlati, forse http://msmvps.com/blogs/jon_skeet/archive/2008/12/10/value-types-and-parameterless-constructors.aspx sarebbe anche di interesse. – kvb

10

Nello spirito di completezza, le risposte che indicano di utilizzare Guid.NewGuid() sono corrette.

In riferimento alla modifica successiva, è necessario inserire il codice per la classe RequestObject. Sospetto che la tua proprietà guid non sia contrassegnata come DataMember e quindi non venga serializzata sul filo. Poiché default(Guid) è lo stesso di new Guid() (ovvero tutti gli 0), ciò spiegherebbe il comportamento che stai vedendo.

Problemi correlati