在不抛出异常的情况下测试字符串是否为 guid? [英] Test if string is a guid without throwing exceptions?
问题描述
我想尝试将字符串转换为 Guid,但我不想依赖捕获异常 (
I want to try to convert a string to a Guid, but I don't want to rely on catching exceptions (
- 出于性能原因 - 异常代价高昂
- 出于可用性原因 - 调试器弹出
- 出于设计原因 - 预期并不例外
换句话说,代码:
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 可以被括号包裹、大括号包裹、无包裹,因此很难.
I would try using RegEx, but since the guid can be parenthesis wrapped, brace wrapped, none wrapped, makes it hard.
此外,我认为某些 Guid 值无效(?)
Additionally, I thought certain Guid values are invalid(?)
更新 1
ChristianK 有一个只捕获 FormatException
的好主意,而不是全部.更改了问题的代码示例以包含建议.
ChristianK had a good idea to catch only FormatException
, rather than all. Changed the question's code sample to include suggestion.
更新 2
为什么要担心抛出的异常?我真的经常期待无效的 GUID 吗?
Why worry about thrown exceptions? Am I really expecting invalid GUIDs all that often?
答案是是.这就是我使用 TryStrToGuid 的原因 - 我我期望得到错误的数据.
The answer is yes. That is why I am using TryStrToGuid - I am expecting bad data.
示例 1 命名空间扩展可以通过将 GUID 附加到文件夹名称来指定.我可能正在解析文件夹名称,检查最终 . 后面的文本是否是 GUID.
Example 1 Namespace extensions can be specified by appending a GUID to a folder name. I might be parsing folder names, checking to see if the text after the final . is a 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 个数量级的资源.
Example 2 I might be running a heavily used web-server wants to check the validity of some posted back data. I don't want invalid data tying up resources 2-3 orders of magnitude higher than it needs to be.
示例 3 我可能正在解析用户输入的搜索表达式.
Example 3 I might be parsing a search expression entered by a user.
如果他们输入 GUID,我想特别处理它们(例如专门搜索该对象,或在响应文本中突出显示和格式化该特定搜索词.)
If they enter GUID's I want to process them specially (such as specifically searching for that object, or highlight and format that specific search term in the response text.)
更新 3 - 性能基准
测试转换 10,000 个好的 Guid 和 10,000 个坏的 Guid.
Test converting 10,000 good Guids, and 10,000 bad Guids.
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.我不应该为一个问题辩护.
推荐答案
性能基准
Catch exception:
10,000 good: 63,668 ticks
10,000 bad: 6,435,609 ticks
Regex Pre-Screen:
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
COM Intertop(最快)答案:
/// <summary>
/// Attempts to convert a string to a guid.
/// </summary>
/// <param name="s">The string to try to convert</param>
/// <param name="value">Upon return will contain the Guid</param>
/// <returns>Returns true if successful, otherwise false</returns>
public static Boolean TryStrToGuid(String s, out Guid value)
{
//ClsidFromString returns the empty guid for null strings
if ((s == null) || (s == ""))
{
value = Guid.Empty;
return false;
}
int hresult = PInvoke.ObjBase.CLSIDFromString(s, out value);
if (hresult >= 0)
{
return true;
}
else
{
value = Guid.Empty;
return false;
}
}
namespace PInvoke
{
class ObjBase
{
/// <summary>
/// This function converts a string generated by the StringFromCLSID function back into the original class identifier.
/// </summary>
/// <param name="sz">String that represents the class identifier</param>
/// <param name="clsid">On return will contain the class identifier</param>
/// <returns>
/// Positive or zero if class identifier was obtained successfully
/// Negative if the call failed
/// </returns>
[DllImport("ole32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = true)]
public static extern int CLSIDFromString(string sz, out Guid clsid);
}
}
<小时>
底线:如果您需要检查字符串是否为 guid,并且您关心性能,请使用 COM Interop.
Bottom line: If you need to check if a string is a guid, and you care about performance, use COM Interop.
如果您需要将字符串表示形式的 guid 转换为 Guid,请使用
If you need to convert a guid in String representation to a Guid, use
new Guid(someString);
这篇关于在不抛出异常的情况下测试字符串是否为 guid?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!