我想尝试将字符串转换为 Guid,但我不想依赖捕获异常(
换句话说,代码:
public static Boolean TryStrToGuid(String s, out Guid value) { try { value = new Guid(s); return true; } catch (FormatException) { value = Guid.Empty; return false; } }
不适合。
我会尝试使用正则表达式,但由于 guid 可以用括号包裹、大括号包裹、不包裹,所以很难。
此外,我认为某些 Guid 值无效(?)
更新 1
有一个好主意,只捕获FormatException,而不是全部。更改了问题的代码示例以包含建议。
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 我可能正在运行一个频繁使用的 Web 服务器,想要检查一些回发数据的有效性。我不希望无效数据占用比所需资源高 2-3 个数量级的资源。
示例 3 我可能正在解析用户输入的搜索表达式。
如果他们输入 GUID,我想专门处理它们(例如专门搜索该对象,或在响应文本中突出显示和格式化该特定搜索词。)
更新 3 - 性能基准
测试转换 10,000 个好的 Guid 和 10,000 个坏的 Guid。
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。
如果您需要将字符串表示形式的 guid 转换为 Guid,请使用
new Guid(someString);