Чи варто навіть перевірити, чи Guid.NewGuid () є Guid.Empty?


28

В одному з проектів, над якими я працюю, наступна закономірність спостерігається досить регулярно:

var guid = Guid.NewGuid().ToString();
while (guid == Guid.Empty.ToString())
{
    guid = Guid.NewGuid().ToString();
}

Хоча я розумію, що aa GUID не гарантовано є унікальним, і відповідно до документації MSDN, створений GUID може дорівнювати нулю , чи це практичне врахування, що насправді варто відправляти на тестування циклів як в обчислювальному сенсі, так і з точки зору часу розробника на його роздуми. ?


1
Якщо ви бачите цю схему неодноразово, можливо, корисний метод був би в порядку? Повторення фрагментів коду, як це, здається більшою проблемою, ніж те, що ви перевіряєте крайовий регістр, який ніколи не відбудеться і може не мати значення, навіть якщо це сталося.
пн.

27
Цей код є, щоб утримати алігаторів подалі. Чи є алігатори, де ви пишете код? Ні? Тоді явно це працює!
Ерік Ліпперт

3
Як би там не було, я би робив це за певний час.
Артуро Торрес Санчес,

3
Чому на землі ти перетворюєш напрямні в рядки і потім порівнюєш? вони порівнюють штрафи самостійно.
Енді

2
Документація була оновлена: «Повернений Guid гарантовано не рівній Guid.Empty.»
sschoof

Відповіді:


33

Я б сказав, що це не варто перевіряти на Guid.Empty. Документи для Guid.NewGuid чомусь згадують про це

Шанс того, що значення нового Guid буде усіма нулями або рівним будь-якому іншому Guid, дуже низький.

Guid.NewGuid - це обгортка для Win32 API CoCreateGuid , яка не згадує про повернення всіх нулів.

Реймонд Чен іде далі , напрошуючи це

жодна дійсна реалізація CoCreateGuid не може генерувати GUID_NULL

Отже, ні, я б не переймався цим. Я не буду здогадуватися, чому документи Guid.NewGuid навіть згадують про це.


1
"І навіть якщо він дійсно генерував GUID_NULL з якоїсь причини, для його унікальності потрібно було б зробити це лише один раз! (Тому ви повинні спробувати змусити цю помилку виникнути в тесті, і тоді ви можете бути впевнені, що вона ніколи не відбудеться у виробництві. ) "- Приємно!
razethestray

3
@razethestray - Ви можете зробити ставку на все, що захочете, в моєму казино.
JeffO

10
@JeffO Жартує вас, він переконався, що 37 разів крутиться вдома і збирається вкласти всі свої гроші на той, який не підійшов.
Випадково832

Що стосується xamarin, Guid.NewGuid іноді виходить з ладу і постійно повертається порожнім (коли керівництво призначається автоматично в ядрі ef), не змогли зрозуміти, чому
Karan Harsh Wardhan

@KaranHarshWardhan Сподіваюся, ви повідомили про це як про помилку. :)
Керт Ніколс

43

Якщо ви виявите, Guid.NewGuid() == Guid.Emptyви виграли найскладнішу лотерею на землі. Не турбуйтеся про перевірку унікальності та зіткнення. Не маючи робити це те , що ідентифікатори GUID є для . Я шкодую вас математики, вона є всюди в Інтернеті.

Також у посібниках Windows завжди є одна "цифра", що дорівнює 4. Існує якась структура для настанов.

Цей фрагмент коду, який ви опублікували, схожий на те, що один розробник забув ініціалізувати Guidзмінну і виявив, що вона є Guid.Empty. Він помилково визначив Guid.NewGuid()причину. Тепер він назавжди забобонно вірить у це.

У будь-якому випадку це неправильне запитання. Я впевнений, що ваш код залежить не тільки від того, хто колись малював, Guid.Emptyа й від унікальності. Цей whileцикл не нав'язує унікальності. Посібники є для створення унікальної цінності без узгодження. Ось такий випадок їх використання.


5
+1 до "неправильного запитання". Вся справа в унікальності, це все, що насправді має значення.
Томас Стрінгер,

1
@rjzii вважаємо прийнятим відповідь!
емкор

18

Подивіться на вихідний код Guid.NewGuidметоду :

public static Guid NewGuid() {
    Contract.Ensures(Contract.Result<Guid>() != Guid.Empty);
    ...
}

Бачите кодовий договір? Guid.NewGuidМетод ніколи не дає порожній GUID.


2
Не впевнений, чому ви отримали прихильний запис, оскільки він згадує те, чого не вистачає в інших відповідях. Наявність кодового договору є досить хорошою гарантією, а також дає чудову відповідь на оригінальне запитання. +1 для ідеї перегляду реальної реалізації.
Арсеній Мурценко

Я люблю кодові договори.
Енді

10

Якщо ви збираєтеся перевіряти GUID проти нульового GUID, вам за тією ж логікою також потрібно зробити належну ретельність, щоб перевірити його проти всіх інших GUID вашої програми (оскільки ймовірність отримати нуль повинна бути такою ж, як ймовірність отримання будь-якого іншого GUID у вашій програмі *). Вам потрібно зробити це, щоб довести, що аксіома, під якою ви працюєте, полягає в тому, що цей GUID буде унікальним (що насправді є тією ж аксіомою, що і тестування проти 0).

Очевидно робити це абсурдно.

TLDR; Якщо ви можете довіряти NewGuid () для отримання унікальних результатів, ви також можете довіряти йому не створювати жодного відомого GUID.

* Його фактично не така ж ймовірність, як .NET GUIDs завжди відповідає наступному, {________-____-4___-____-____________}тому NewGuid НІКОЛИ не генерує нульову орієнтир

Для розваги я запропонував удосконалити документи тут: http://feedback.msdn.com/forums/257782-msdn-feature-suggestions/suggestions/7143498-fix-documentation-for-newguid


3
Чому .NET GUIDs завжди включає 4?
Артуро Торрес Санчес,

9
@ ArturoTorresSánchez: Щодо відповіді на ваше запитання та ще багатьох цікавих фактів про GUID, дивіться мою серію статей, яка починається тут ericlippert.com/2012/04/24/guid-guide-part-one Зауважу, що Лука вже зв’язав частину третю для вашої зручності. Коротка відповідь: GUID версії 4 завжди містять 4.
Ерік Ліпперт

@EricLippert - це дуже гарна стаття :)
Не любив Не своїх людей,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.