Guid.NewGuid () vs. nowy Guid ()

347

Jaka jest różnica między Guid.NewGuid()i new Guid()?

Który jest preferowany?

OscarRyz
źródło
6
@ClintonWard Jestem praktycznie nowy w C # i @ Bob2Chiv Nie mogę teraz uruchomić projektu i byłem ciekawy.
OscarRyz
6
@OscarRyz - Do szybkiego testowania kodu w C # używam LinqPad .
DaveShaw,
5
Właściwie uważam, że to pytanie jest istotne, ponieważ jest mylące i tak naprawdę nie „0000000-0000 ..” jako najlepszy domyślny. Właśnie natknąłem się na problem polegający na tym, że klient nie mógł zalogować się do systemu, ponieważ gdzieś w głębi projektu wywołano nową Guid () zamiast NewGuid ()
Michiel Cornille
3
@DaveShaw - LinQPad jest świetny i często go używam. Chciałem jednak zauważyć, że Visual Studio ma teraz okno „C # Interactive”, które jest bardzo przydatne w tego rodzaju testach.
Mark Meuer
1
@MichielCornille Właśnie poznałem uczucie bracie ...
Jins Peter

Odpowiedzi:

583

new Guid() sprawia, że ​​„pusta” wartość „0” (00000000-0000-0000-0000-000000000000 nie jest zbyt przydatna).

Guid.NewGuid() tworzy prawdziwy przewodnik z unikalną wartością, czego prawdopodobnie chcesz.

MarkPflug
źródło
26
Pusty identyfikator UUID jest rzeczywiście bardzo przydatny. To sprawia, że ​​jest to wyjątkowa wartość.
Jon Hanna,
103
Na marginesie new Guid()odpowiada Guid.Empty.
Steve Guidi,
30
@JonHanna Wszystkie przewodniki mają wielkie wartości specjalne. Niestety te puste mają tendencję do kolizji. Zgadzam się, że puste przewodniki są przydatne, zwykle w celu wskazania, że ​​coś jest niezainicjowane.
MarkPflug,
5
Puste są bardzo przydatne, ponieważ się zderzają. Specjalna wartość, która nie koliduje ze znaną wartością specjalną, byłaby bezużyteczna.
Jon Hanna,
5
Myślę, że oboje zgadzacie się, że jest to dobry „znany przewodnik” do porównania, jak w przypadku wskazania, że ​​coś oczekuje na inicjalizację lub jest w innym znanym stanie. Osobiście wolałbym użyć wartości zerowej, ale widzę, że ktoś może potrzebować „specjalnego” przewodnika w pewnym momencie, a przewodnik „0” jest prawdopodobnie przewodnikiem, który prawdopodobnie nie naruszy zasady najmniejszej niespodzianki dla przyszłych opiekunów kodu.
PeterL,
37

Guid.NewGuid() tworzy nowy UUID za pomocą algorytmu zaprojektowanego tak, aby kolizje były bardzo, bardzo mało prawdopodobne.

new Guid() tworzy identyfikator UUID składający się z samych zer.

Zasadniczo wolałbyś ten pierwszy, ponieważ o to chodzi w UUID (chyba że otrzymujesz go skądś indziej).

Istnieją przypadki, gdzie rzeczywiście chce się wszystko od zera UUID, ale w tym przypadku, Guid.Emptyczy default(Guid)jest jaśniejszy o swoją intencją, i jest mniejsza szansa, że ktoś czyta to spodziewa się unikalną wartość został utworzony.

Podsumowując, new Guid()nie jest to użyteczne z powodu tego braku jasności, ale nie można mieć typu wartości, który nie ma konstruktora bez parametrów, który zwraca wartość zera i zera.

Edycja: W rzeczywistości możliwe jest posiadanie konstruktora bez parametrów na typ wartości, który nie ustawia wszystkiego na zero i zero, ale nie można tego zrobić w języku C # i regułach określających, kiedy zostanie on wywołany, a kiedy będzie po prostu bądź strukturą zero, są tworzone mylące, więc i tak nie jest to dobry pomysł.

Jon Hanna
źródło
16
Dodam to dla zabawy. Aby mieć 1% szansy na kolizję, musisz wygenerować około 2 600 000 000 000 000 000 GUID
Clinton Ward
8
@ClintonWard zależy od tego, który z algorytmów UUID jest używany, ale ponieważ niektórzy używają adresów MAC, aby uniknąć kolizji między komputerami, i wszyscy używają współczynnika czasu, aby uniknąć kolizji na tym samym komputerze, musisz stworzyć nawet więcej niż normalna matematyka zasugerował. Chyba że celowo wkręcasz algorytm, zmieniając czas i psując adresy MAC, w takim przypadku powinieneś dostać jeden bardzo szybko - ale to celowo psuje dane wejściowe.
Jon Hanna,
2
To był Guid v1. nowsze MS GUID to V4 i nie używają adresu MAC w ramach generowania GUID. Czas jest jednak nadal istotny
Clinton Ward
16

[Rozumiem, że to stary wątek, tylko dodając trochę więcej szczegółów] Dwie odpowiedzi Marka i Jona Hanny podsumowują różnice, chociaż może to zainteresować

Guid.NewGuid()

W końcu wywołuje CoCreateGuid (wywołanie COM do Ole32) (odniesienie tutaj ), a faktyczna praca jest wykonywana przez UuidCreate .

Guid.Empty służy do sprawdzania, czy Guid zawiera wszystkie zera. Można to również zrobić poprzez porównanie wartości omawianego Guida z nowym Guid ()

Jeśli potrzebujesz unikalnego identyfikatora , odpowiedzią jest Guid.NewGuid ()

Sudhanshu Mishra
źródło
-2

Guid.NewGuid(), ponieważ tworzy identyfikatory GUID zgodnie z przeznaczeniem.

Guid.NewGuid()tworzy pusty Guidobiekt, inicjuje go, wywołując CoCreateGuidi zwraca obiekt.

new Guid() tworzy jedynie pusty identyfikator GUID (chyba wszystkie zera).

Myślę, że musieli upublicznić konstruktora tak jak Guidjest struct.

Sharath
źródło
5
Po co dodawać odpowiedź, która nie dodaje niczego, co już nie istnieje w odpowiedziach, które są tu od lat?
Dinerdo