Guid to wszystkie zera (zera)?


241

Testuję niektóre usługi WCF, które wysyłają obiekty z Guidami tam iz powrotem. W moim kodzie testowym aplikacji internetowej wykonuję następujące czynności:

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

Z jakiegoś powodu wywołanie new Guid () generuje Guids ze wszystkimi zerami (0) w następujący sposób:

00000000-0000-0000-0000-000000000000

Co może być tego przyczyną?


9
Po twojej edycji jest to zupełnie nowe pytanie. Aby ustalić nową odpowiedź, potrzeba znacznie więcej informacji.
Scott Rippey,

3
Usunięto edytowaną część, która zmieniła pytanie.
Didaxis,

115
+1, ponieważ użyłem tego pytania do kradzieży pustego przewodnika kilkanaście razy :)
jmosesman

5
@ jmosesman, lepiej skorzystać z formularzaGuid.Empty
Jonathan Moosekian

4
@JonathanM Właściwie używam go w skrypcie SQL. Ten post pojawia się pierwszy po wyszukiwaniu.
jmosesman

Odpowiedzi:


428

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

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

18
+1 za poprawną odpowiedź oraz link do właściwej dokumentacji.
ObscureRobot

109

Wnioski z tego wynikające:

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

2) Wywołanie domyślnego konstruktora new S()dla dowolnego typu wartości zawsze daje z powrotem postać zerową tego typu wartości, niezależnie od tego, co to jest. Jest logicznie taki sam jak default(S).


3
Czy można go skompilować do tej samej IL-y, default(S)czy brakuje mi subtelności?
konfigurator

8
@configurator: Tak. W rzeczywistości wewnętrzna reprezentacja kompilatora „default (S)” i „new S ()” są takie same; nie odróżnić je od wewnątrz, co doprowadziło do pewnych niefortunnych błędów na przestrzeni lat, ponieważ są one w rzeczywistości nie całkiem identyczne. Na przykład const int x = new int();nie powinien być zgodny ze specyfikacją, ale const int x = default(int);jest; pozwalamy na jedno i drugie.
Eric Lippert,

1
@ konfigurator @ - jeśli interesują Cię powiązane sprawy narożne, być może zainteresuje Cię również msmvps.com/blogs/jon_skeet/archive/2008/12/10/....
kvb 7.11.11

56

Spróbuj zamiast tego:

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

To wygeneruje „prawdziwą” wartość Guid. Kiedy nowy typ referencji, da ci wartość domyślną (która w tym przypadku to wszystkie zera dla Guida).

Kiedy utworzysz nowego Guida, zainicjuje go on do wszystkich zer, co jest wartością domyślną dla Guida. Jest to w zasadzie to samo, co tworzenie „nowego” int (który jest typem wartości, ale możesz to zrobić mimo to):

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 do robienia tego samego z int:

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

1
g1skompiluje się tylko jako zmienna pola, a nie jako zmienna lokalna. Również indeksy w kolumnie komentarza nie pasują do tego samego wiersza kodu
CodesInChaos

1
@CodeInChaos: Dzięki, naprawiono komentarze. Do Twojej wiadomości, linia g1 faktycznie się kompiluje ...
JohnD

3
Skompiluje się tak, jak jest, ale nie ma zdefiniowanej wartości. Jeśli dodasz kod, który czyta go (przed zapisaniem), nie będzie się już kompilował.
CodesInChaos

1
Dobra, dobra uwaga, jeśli użyjesz niezainicjowanej zmiennej, pojawi się błąd, więc nie można użyć tej wartości.
JohnD,

1
głosowano w dół, ponieważ wiersz „Guid = Guid.NewGuid ();” może mylić nowszych programistów. Rozważ edycję do czegoś takiego jak „Guid someGuid = Guid.NewGuid ();” jak linia g2;)
daviesdoesit


19

Nie mogę powiedzieć, ile razy to się złapało. mnie.

Guid myGuid = Guid.NewGuid(); 

11

W duchu kompletności odpowiedzi, które instruują cię do użycia, Guid.NewGuid()są poprawne.

W odpowiedzi na kolejną edycję musisz opublikować kod swojej RequestObjectklasy. Podejrzewam, że twoja właściwość GUID nie jest oznaczona jako DataMember, a zatem nie jest serializowana przez sieć . Ponieważ default(Guid)jest to to samo co new Guid()(tzn. Wszystkie 0), to wyjaśniałoby zachowanie, które widzisz.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.