If you are targeting a GUID in hex form, you can check that the string is 32-characters long (after stripping dashes and curly brackets) and has only letters A-F and numbers. from http://www.geekzilla.co.uk/view8AD536EF-BC0D-427F-9F15-3A1BC663848E.htm.
#4: A Guid has multiple formats Well, no: those are part of the default string representation of a Guid. When using the ToString() method you can specify the format that you want.
The valid GUID (Globally Unique Identifier) must specify the following conditions: It should be a 128-bit number. It should be 36 characters (32 hexadecimal characters and 4 hyphens) long. It should be displayed in five groups separated by hyphens (-).
guidVal. ToString("N") returns 32 hex digits: 00000000000000000000000000000000. guidVal. ToString("B") returns 32 hex digits separated by hyphens, enclosed in braces: {00000000-0000-0000-0000-000000000000}
Performance Benchmarks
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 (Fastest) Answer:
/// <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);
}
}
Bottom line: If you need to check if a string is a guid, and you care about performance, use COM Interop.
If you need to convert a guid in String representation to a Guid, use
new Guid(someString);
Once .net 4.0 is available you can use Guid.TryParse()
.
You're not going to like this but what makes you think that catching the exception is going to be slower?
How many failed attempts to parse a GUID are you expecting in comparison with successful ones?
My advice is use the function you've just created and profile your code. If you find that this function is truely a hotspot then fix it but not before.
In .NET 4.0 you can write as following:
public static bool IsValidGuid(string str)
{
Guid guid;
return Guid.TryParse(str, out guid);
}
I would at least rewrite it as:
try
{
value = new Guid(s);
return true;
}
catch (FormatException)
{
value = Guid.Empty;
return false;
}
You don't want to say "invalid GUID" on SEHException, ThreadAbortException or other fatal or non-related stuff.
Update: Starting with .NET 4.0, there is a new set of methods available for Guid:
Guid.TryParse
Guid.TryParseExact
Really, those should be used (if only for the fact, that they are not "naively" implemented using try-catch internally).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With