Я хочу попытаться преобразовать строку в Guid, но я не хочу полагаться на перехват исключений (
- по причинам производительности - исключения дорогие
- по соображениям удобства использования - появляется отладчик
- по конструктивным причинам - ожидаемое не исключение
Другими словами код:
public static Boolean TryStrToGuid(String s, out Guid value)
{
try
{
value = new Guid(s);
return true;
}
catch (FormatException)
{
value = Guid.Empty;
return false;
}
}
не подходит.
Я бы попробовал использовать RegEx, но так как guid может быть заключен в скобки, заключен в скобки, ни один не обернут, это затрудняет работу.
Кроме того, я думал, что некоторые значения Guid являются недействительными (?)
Обновление 1
У ChristianK была хорошая идея ловить только FormatException
, а не все. Изменен пример кода вопроса, чтобы включить предложение.
Обновление 2
Зачем беспокоиться о брошенных исключениях? Неужели я так часто жду неверных идентификаторов GUID?
Ответ - да . Именно поэтому я использую TryStrToGuid - я имею ожидая плохие данные.
Пример 1 Расширения пространства имен можно указать, добавив GUID к имени папки . Возможно, я разбираю имена папок, проверяя, есть ли текст после финала . это GUID.
c:\Program Files
c:\Program Files.old
c:\Users
c:\Users.old
c:\UserManager.{CE7F5AA5-6832-43FE-BAE1-80D14CD8F666}
c:\Windows
c:\Windows.old
Пример 2 Возможно, я использую интенсивно используемый веб-сервер, который хочет проверить достоверность некоторых опубликованных данных. Я не хочу, чтобы недопустимые данные связывали ресурсы на 2-3 порядка выше, чем нужно.
Пример 3 Я могу проанализировать поисковое выражение, введенное пользователем.
Если они вводят GUID, я хочу специально обработать их (например, специально искать этот объект или выделить и отформатировать этот конкретный поисковый термин в тексте ответа).
Обновление 3 - Тесты производительности
Тест на преобразование 10 000 хороших гидов и 10 000 плохих гидов.
Catch FormatException:
10,000 good: 63,668 ticks
10,000 bad: 6,435,609 ticks
Regex Pre-Screen with try-catch:
10,000 good: 637,633 ticks
10,000 bad: 717,894 ticks
COM Interop CLSIDFromString
10,000 good: 126,120 ticks
10,000 bad: 23,134 ticks
PS Мне не нужно было обосновывать вопрос.
4.0
. Вот почему вопрос и принятый ответ таковы.Ответы:
Тесты производительности
COM Intertop (Самый быстрый) Ответ:
Итог: если вам нужно проверить, является ли строка guid, и вы заботитесь о производительности, используйте COM Interop.
Если вам нужно преобразовать guid в представлении String в Guid, используйте
источник
Как только .net 4.0 станет доступен, вы можете использовать
Guid.TryParse()
.источник
Вам это не понравится, но с чего вы взяли, что поймать исключение будет медленнее?
Сколько неудачных попыток разобрать GUID вы ожидаете по сравнению с успешными?
Мой совет - используйте только что созданную функцию и профилируйте свой код. Если вы обнаружите, что эта функция действительно горячая точка, то исправьте ее, но не раньше.
источник
В .NET 4.0 вы можете написать следующее:
источник
Я бы хотя бы переписал это так:
Вы не хотите произносить «недопустимый GUID» в SEHException, ThreadAbortException или других фатальных или не связанных вещах.
Обновление : Начиная с .NET 4.0, для Guid доступен новый набор методов:
Guid.TryParse
Guid.TryParseExact
Действительно, их следует использовать (хотя бы потому, что они не «наивно» реализованы с использованием try-catch внутри).
источник
Взаимодействие медленнее, чем просто ловить исключение:
На счастливом пути с 10 000 гидов:
На несчастном пути:
Это более последовательно, но также постоянно медленнее. Мне кажется, вам лучше настроить свой отладчик так, чтобы он работал только на необработанных исключениях.
источник
Ну, вот вам и регулярное выражение ...
Но это только для начала. Вам также необходимо убедиться, что различные части, такие как дата / время, находятся в допустимых пределах. Я не могу представить, что это происходит быстрее, чем метод try / catch, который вы уже описали. Надеюсь, вы не получите столько недействительных идентификаторов GUID, чтобы гарантировать такой тип проверки!
источник
Если вы собираетесь использовать подход try / catch, вы можете добавить атрибут [System.Diagnostics.DebuggerHidden], чтобы убедиться, что отладчик не ломается, даже если вы установили его как разрыв на бросок.
источник
Несмотря на то , что это правда , что использование ошибок является более дорогим, большинство людей считают , что большинство их GUIDs будет компьютером так
TRY-CATCH
не слишком дорого , так как это создает только стоимость наCATCH
. Вы можете доказать это сами с помощью простого теста из двух (публичный пользователь, без пароля).Ну вот:
источник
У меня была похожая ситуация, и я заметил, что почти никогда не было неверной строки длиной 36 символов. Поэтому, основываясь на этом факте, я немного изменил ваш код, чтобы повысить производительность, сохранив при этом простоту.
источник
Насколько я знаю, в mscrolib нет ничего похожего на Guid.TryParse. Согласно Reference Source, тип Guid имеет мега-сложный конструктор, который проверяет все виды форматов guid и пытается их проанализировать. Нет вспомогательного метода, который вы можете вызвать, даже с помощью отражения. Я думаю, что вы должны искать сторонние парсеры Guid или написать свой собственный.
источник
Запустите потенциальный GUID, хотя RegEx или некоторый пользовательский код, который проверяет работоспособность, чтобы убедиться, что стринг, по крайней мере, выглядит как GUID и состоит только из допустимых символов (и, возможно, он соответствует общему формату). Если он не пройдет проверку исправности, верните ошибку - это, вероятно, отсеет подавляющее большинство неверных строк.
Затем преобразуйте строку, как описано выше, по-прежнему перехватывая исключение для нескольких недопустимых строк, которые проходят проверку работоспособности.
Джон Скит (Jon Skeet) провел анализ чего-то похожего для разбора Ints (до того, как TryParse появился в Framework): проверка возможности преобразования строки в Int32
Однако, как указал AnthonyWJones, вам, вероятно, не стоит беспокоиться об этом.
источник
источник
Ctor Guid - это в значительной степени скомпилированное регулярное выражение, так что вы получите точно такое же поведение без дополнительных затрат на исключение.
Еще более удачным решением было бы динамическое применение метода, заменив «бросить новый» на лету.
источник
Я голосую за ссылку GuidTryParse, размещенную выше Джоном или аналогичным решением (IsProbblyGuid). Я напишу такой же для моей библиотеки конверсий.
Я думаю, что это совершенно неубедительно, что этот вопрос должен быть настолько сложным. Ключевое слово "is" или "as" было бы просто замечательно, если бы Guid мог быть нулевым. Но по какой-то причине, хотя с SQL Server все в порядке, .NET - нет. Зачем? Какова стоимость Guid.Empty? Это просто глупая проблема, созданная при разработке .NET, и она действительно беспокоит меня, когда соглашения о языке наступают сами собой. Самый эффективный ответ до сих пор - использование COM Interop, потому что Framework не справляется с этим изящно? "Может ли эта строка быть GUID?" должен быть вопрос, на который легко ответить.
Можно полагаться на исключение, пока приложение не появится в Интернете. В этот момент я просто настроился на атаку отказа в обслуживании. Даже если я не буду «атакован», я знаю, что некоторые из них собираются поэкспериментировать с URL-адресом, или, возможно, мой отдел маркетинга отправит неверно сформированную ссылку, и тогда мое приложение должно испытать довольно высокую производительность, которую МОЖЕТ принести на сервере, потому что я не написал свой код для решения проблемы, которая НЕ ДОЛЖНА произойти, но мы все знаем, что БУДЕТ.
Это немного размывает строку «Исключение» - но суть в том, что даже если проблема нечастая, если за короткое время может произойти достаточное количество раз, когда ваше приложение аварийно завершает работу, отлавливая все эти ловушки, то я думаю, что выбрасывание исключения плохой тон.
TheRage3K
источник
если TypeOf ctype (myvar, Object) является Guid, то .....
источник
источник
С методом расширения в C #
источник