Стоит ли даже проверять, является ли Guid.NewGuid () Guid.Empty?

28

В одном из проектов, над которым я работаю, следующая картина видится довольно регулярно:

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

Хотя я понимаю, что GUID не гарантированно является уникальным, и в соответствии с документацией MSDN сгенерированный GUID может быть равен нулю , это практическое соображение на самом деле стоит посылать циклическое тестирование как в вычислительном смысле, так и с точки зрения времени разработчика, думая об этом ?

rjzii
источник
1
Если вы видите этот шаблон неоднократно, возможно, будет полезен служебный метод? Повторение фрагментов кода, подобных этому, кажется более серьезной проблемой, чем тот факт, что вы проверяете крайний случай, который никогда не произойдет и может не иметь значения, даже если это произошло.
PSR
27
Этот код предназначен для того, чтобы держать аллигаторов подальше. Есть ли аллигаторы, где вы пишете код? Нет? Тогда, очевидно, это работает!
Эрик Липперт
3
В любом случае, я бы сделал это в ближайшее время.
Артуро Торрес Санчес
3
С какой стати вы конвертируете направляющие в струны, а затем сравниваете? они хорошо сравнивают сами по себе.
Энди
2
Документация была обновлена: «Возвращенный Guid гарантированно не равной Guid.Empty.»
schoof

Ответы:

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 раз и собирается положить все свои деньги на тот, который не подошел.
Random832 25.02.15
На xamarin Guid.NewGuid иногда дает сбой и постоянно возвращается пустым (когда guid автоматически назначается в ef core), так и не смог понять, почему
Каран Харш Вардхан
@KaranHarshWardhan Я надеюсь, что вы сообщили об этом как об ошибке. :)
Курт Николс
43

Если вы обнаружите Guid.NewGuid() == Guid.Empty, что выиграли самую сложную лотерею на земле. Не беспокойтесь ни о какой уникальности или проверке столкновений. Не имея делать это то , что идентификаторы GUID являются для . Я избавлю вас от математики, это везде в сети.

Кроме того, направляющие Windows всегда имеют одну «цифру», равную 4. Существует некоторая структура для гидов.

Этот фрагмент кода, который вы разместили, выглядит так, как будто один разработчик забыл инициализировать Guidпеременную и обнаружил, что это так Guid.Empty. Он ошибочно определен Guid.NewGuid()как причина. Теперь он навсегда суеверно поверит в это.

В любом случае это неправильный вопрос. Я уверен, что ваш код зависит не только от рисования, Guid.Emptyно и от уникальности. Этот whileцикл не обеспечивает уникальность. Гиды должны создать уникальную ценность без координации. Это их вариант использования.

USR
источник
5
+1 к «неправильному вопросу». Все дело в уникальности, это все, что действительно имеет значение.
Томас Стрингер
1
@rjzii подумайте над тем, чтобы сделать этот ответ принятым!
Эмкор
18

Посмотрите на исходный код Guid.NewGuidметода :

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

Видите код договора? Guid.NewGuidМетод никогда не дает пустой GUID.

sschoof
источник
2
Не уверен, почему вы получили отрицательное голосование, поскольку в нем упоминается то, чего не хватает в других ответах. Наличие кода контракта является довольно хорошей гарантией, а также дает отличный ответ на оригинальный вопрос. +1 за идею посмотреть на фактическую реализацию.
Арсений Мурзенко
Я люблю кодовые контракты.
Энди
10

Если вы собираетесь проверять GUID по нулевому GUID, вам по той же логике также необходимо провести тщательную проверку его по всем остальным GUID в вашем приложении (поскольку вероятность получения нуля должна совпадать с вероятностью получить любой другой GUID в вашем приложении *). Вы должны сделать это, чтобы доказать, что аксиома, под которой вы действуете, состоит в том, что этот GUID будет уникальным (что на самом деле та же самая аксиома, что и при тестировании против 0).

Очевидно, что делать это абсурдно.

TLDR; Если вы можете доверять NewGuid () для получения уникальных результатов, вы также можете доверять ему, чтобы он не создавал ни одного известного GUID.

* На самом деле это не та вероятность, что .NET GUID всегда соответствуют следующему, {________-____-4___-____-____________}поэтому NewGuid НИКОГДА не сгенерирует нулевую направляющую.

Просто для забавы я предложил улучшить документы здесь: http://feedback.msdn.com/forums/257782-msdn-feature-suggestions/suggestions/7143498-fix-documentation-for-newguid

Не любил не своих людей
источник
3
Почему .NET GUID всегда включают 4?
Артуро Торрес Санчес
9
@ ArturoTorresSánchez: ответ на ваш вопрос и много других интересных фактов о GUID см. В моей серии статей, которая начинается здесь. ericlippert.com/2012/04/24/guid-guide-part-one Хочу заметить, что Люк уже связан с третьей частью для вашего удобства. Краткий ответ: GUID версии 4 всегда включает 4.
Эрик Липперт
@EricLippert это очень хорошая статья :)
Не любил Не их люди