Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test if string is a guid without throwing exceptions?

People also ask

How do you test if a string is a GUID?

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.

Is a GUID a string?

#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.

What makes a valid GUID?

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 (-).

Can you convert GUID to string?

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).