2011-11-01 10 views
173

Testuję niektóre usługi WCF, które wysyłają obiekty z Guids tam iz powrotem. W moim internetowej kodzie aplikacji testowej, robię co następuje:Guid to zero (wszystkie)?

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

Z jakiegoś powodu wywołanie nowy GUID() generuje GUID ze wszystkimi 0'S (zer) tak:

00000000-0000-0000-0000-000000000000

Co może być przyczyną?

+8

Po edycji jest to zupełnie nowe pytanie. I dużo więcej informacji jest potrzebnych do ustalenia nowej odpowiedzi. –

+0

Nakładanie się: http://stackoverflow.com/q/7972658/60761 –

+2

Usunięto edytowany fragment, który zmienił pytanie. – Didaxis

Odpowiedz

332

Użyj metody statycznej Guid.NewGuid() zamiast wywoływania domyślnego konstruktora.

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

+1 za poprawną odpowiedź, a także łącze do odpowiedniej dokumentacji. – ObscureRobot

17

Spróbuj to zrobić:

Guid = Guid.NewGuid(); 
16

Nie mogę powiedzieć ile razy ten został złapany. mnie.

Guid myGuid = Guid.NewGuid(); 
54

Spróbuj to zamiast:

Guid = Guid.NewGuid(); 

To wygeneruje 'prawdziwej' wartości GUID. Po dodaniu nowego typu referencyjnego otrzymasz wartość domyślną (która w tym przypadku jest zerowa dla Guida).

Gdy utworzysz nowy Guid, zainicjuje on wszystkie zera, co jest domyślną wartością Guid. Jest to w zasadzie taki sam jak stworzenie „nowego” int (co jest typ wartości, ale można to zrobić tak czy inaczej):

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 

Porównaj to robi to samo z int:

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

'g1' będzie kompilowany tylko jako pole, a nie jako zmienna lokalna. Również indeksy w kolumnie komentarza nie pasują do tego samego wiersza kodu: – CodesInChaos

+0

@CodeInChaos: Dzięki, poprawiono komentarze. FYI, linia g1 faktycznie się kompiluje ... – JohnD

+2

Kompiluje się tak jak jest, ale nie ma zdefiniowanej wartości. Jeśli dodasz kod, który je czyta (przed napisaniem do niego), nie będzie on już kompilowany. – CodesInChaos

99

Lekcje do nauczenia się z tego:

1) Guid jest typem wartości, a nie typem referencyjnym.

2) Wywołanie domyślnego konstruktora new S() dla dowolnego typu wartości zawsze daje powrót do postaci zerowej tego typu wartości, bez względu na to, jaki jest. Jest logicznie taki sam jak default(S).

+1

Czy kompiluje się do tej samej IL co 'default (S)' lub czy są jakieś subtelności, których mi brakuje? – configurator

+5

@configurator: Tak. W rzeczywistości wewnętrzna reprezentacja kompilatora "default (S)" i "new S()" są takie same; nie rozróżniamy ich wewnętrznie, co doprowadziło do pewnych niefortunnych błędów na przestrzeni lat, ponieważ w rzeczywistości nie są * całkiem * identyczne. Na przykład 'const int x = new int();' nie powinien być legalny zgodnie ze specyfikacją, ale 'const int x = default (int);' is; pozwalamy na oba. –

+0

@configurator - jeśli interesują Cię pokrewne przypadki narożne, być może http://msmvps.com/blogs/jon_skeet/archive/2008/12/10/value-types-and-parameterless-constructors.aspx będzie również zainteresowanie. – kvb

10

W duchu bycia kompletnym, odpowiedzi, które instruują cię do używania Guid.NewGuid() są poprawne.

Podczas kierowania do kolejnej edycji musisz opublikować kod dla swojej klasy RequestObject. Podejrzewam, że twoja własność guid nie jest oznaczona jako DataMember, a zatem nie jest serializowana przez przewód. Ponieważ default(Guid) jest taki sam jak new Guid() (tj. Wszystkie 0), to wyjaśniałoby to zachowanie, które widzisz.