In this article, we will explore several approaches to validate a string representation of a GUID in C#.

To download the source code for this article, you can visit our GitHub repository.

So let’s dive in.

What Does a GUID Look Like?

The term “GUID” was first introduced by Microsoft as a specific version of the broader term “Universally Unique Identifier” (UUID). As time passed, these terms have become interchangeable, with their usage standardized by RFC 4122. In C#, a GUID is a 128-bit unique identifier commonly represented as a 32-character hexadecimal string in the format “xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”, where each “x” represents a hexadecimal digit (0-9, A-F).

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

GUIDs play a pivotal role in programming, serving as universally unique identifiers across distributed systems and applications. They offer a dependable mechanism for generating identifiers that are highly unlikely to collide or be duplicated. GUIDs find extensive use in various scenarios, including primary keys, unique constraints in databases, session identifiers, and resource naming, among others.

For a deeper understanding, please consult our comprehensive article Working With Guid in C#.

Approaches To Validate a GUID in C#

Given their diverse applications and critical roles in our implementations, GUIDs warrant special attention. Specifically, when handling data that is anticipated to be a GUID but arrives as a string or in another format, it becomes crucial to verify the authenticity of the incoming value to maintain data integrity and ensure the correctness of operations involving GUIDs.

Let’s explore some approaches for determining whether a string contains a GUID or just a sequence of characters.

Regular Expressions

Utilizing regular expressions enables us to recognize GUIDs within strings. We understand that GUIDs adhere to a fixed length of 36 characters, including hyphens. By crafting a regex pattern that aligns with the GUID format, we can precisely pinpoint GUID occurrences within strings.

Let’s harness the potency of regular expressions for identifying strings as GUIDs:

public partial class GuidHelper
{
    [GeneratedRegex("^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$")]
    private static partial Regex GuidValidatorRegex();
}

Here, we introduce a GuidHelper class to streamline the validation process for GUIDs. Within this class, we leverage the innovative GeneratedRegex attribute. It takes a regex pattern and harnesses the capabilities of Roslyn Source Generator to dynamically generate the source code of a regular expression during compile time instead of runtime. This approach promises faster regex execution, thereby enhancing the overall performance of the application. To accomplish this, we define a partial method named GuidValidatorRegex(), which returns a Regex type response and utilizes the GeneratedRegex attribute to reinforce its functionality.

When formulating the pattern, we specify that the input must consist of five parts separated by hyphens. The first part should be 8 characters long, the final part 12 characters long, and the remaining parts 4 characters each. Each part must comprise either a numerical value (0-9) or a character ranging from A to F. The total length, including hyphens, is 36 characters.

Let’s see how we can use this feature:

public static bool ValidateWithRegex(string input)
{
    return GuidValidatorRegex().IsMatch(input);
}

Here, we establish a helper method ValidateWithRegex(), which accepts a string input parameter. Within this method, we utilize the previously defined GuidValidatorRegex() function and invoke the IsMatch() method to validate the input string.

Let’s invoke this method with both GUID and non-GUID inputs:

var guidString = Guid.NewGuid().ToString();
const string nonGuidString = "loremipsum-sid-dolar-amet-34648208e86d";
const string messageFormat = "{0} | guidString is {1}, nonGuidString is {2}";

Message("Regex", GuidHelper.ValidateWithRegex(guidString), GuidHelper.ValidateWithRegex(nonGuidString));

Let’s now inspect the result:

Regex | guidString is GUID, nonGuidString is not a GUID

As expected, our guidString is a valid GUID, while our nonGuidString is not.

Guid.Parse To Validate a GUID in C#

We can use the Guid.Parse() method in C# to convert either a string or a character span into a GUID value. It first trims any leading or trailing white space characters from the input before processing the remaining characters to generate a GUID. Then, it processes the remaining characters to generate a GUID. If the method encounters difficulties in parsing the string, it promptly throws a FormatException.

Let’s use this method to validate whether a string is a GUID or not:

public static bool ValidateWithGuidParse(string input)
{
    try
    {
        Guid.Parse(input);
    }
    catch (FormatException)
    {
        return false;
    }

    return true;
}

Here, we introduce the ValidateWithGuidParse() method, which accepts a string input parameter. Within the method, we use the Guid.Parse() method in a try-catch block. If the input is valid, no exception is thrown. However, if an invalid input is provided, the method will raise a FormatException.

From this point onward, we will omit the steps for invoking and verifying the result, as they closely resemble those used in the regex approach.

Guid.ParseExact To Validate a GUID in C#

Another essential tool for validating whether a string is a GUID or not is the Guid.ParseExact() method in C#. Like the Guid.Parse() method, it’s part of the System.Guid namespace and serves to parse a string representation of a GUID into a Guid structure. With one difference! It takes a format parameter, allowing us to enforce a specific format for the input string, and provides more control over the parsing process compared to the Guid.Parse() method.

The format parameter dictates the formatting of the GUID string, determining factors such as the placement and type of separators (e.g., hyphens, braces). It supports various format specifiers:

FormatDescription
NRepresents 32 digits without hyphens (e.g., "6F9619FF8B86D011B42D00C04FC964FF").
DRepresents 32 digits separated by hyphens in the standard 8-4-4-4-12 format (e.g., “6F9619FF-8B86-D011-B42D-00C04FC964FF”).
BRepresents 32 digits separated by hyphens and enclosed in braces (e.g., “{6F9619FF-8B86-D011-B42D-00C04FC964FF}”).
PRepresents 32 digits separated by hyphens and enclosed in parentheses (e.g., “(6F9619FF-8B86-D011-B42D-00C04FC964FF)”).

This method enhances precision and flexibility in validating and parsing GUID strings, ensuring adherence to specific formatting requirements.

Let’s utilize this method to validate a GUID:

public static bool ValidateWithGuidParseExact(string input, string format)
{
    try
    {
        Guid.ParseExact(input, format);
    }
    catch (FormatException)
    {
        return false;
    }

    return true;
}

Here, we define the ValidateWithGuidParseExact() method. Inside the method, we invoke the Guid.ParseExact() method with the coming input parameter and a format parameter "D". Likewise, the ValidateWithGuidParse() method, if invalid input is provided, the method will raise a FormatException.

Guid.TryParse To Validate a GUID in C#

In comparison to the Guid.Parse() and Guid.ParseExact() methods, Guid.TryParse() offers a safer approach to validate whether a string is a GUID. Rather than throwing an exception, Guid.TryParse() returns a boolean value indicating the success or failure of the parsing operation.

Let’s illustrate its usage:

public static bool ValidateWithGuidTryParse(string input)
{
    return Guid.TryParse(input, out Guid _);
}

Here, we create the ValidateWithGuidTryParse() method. It simply invokes and returns the result of Guid.TryParse() method.

Guid.TryParseExact To Validate a GUID in C#

If we prefer to sidestep the complexities of exceptions and our string conforms precisely to a predefined GUID format, then let’s embrace the Guid.TryParseExact() method. Likewise the Guid.ParseExact() method, this approach necessitates the string to precisely match the format specified by the format parameter, following the removal of any leading or trailing white-space characters. If the input is null or doesn’t conform to the specified format, the method returns false without throwing an exception:

public static bool ValidateWithGuidTryParseExact(string input, string format)
{
    return Guid.TryParseExact(input, format, out Guid _);
}

Here, we introduce the ValidateWithGuidTryParseExact() method, which takes a parameter, input to validate based on the format parameter. In the method, we use the Guid.TryParseExact() method and return the result of it.

Guid Constructor

When it comes to finding a solution in programming, there are often multiple approaches available. Given that our objective is to verify whether a string represents a GUID, we might indirectly repurpose the new Guid() structure as a validation method. We know that passing a value to the new Guid() constructor results in a successful instance if it’s a valid GUID. However, if the input format is not suitable for a GUID, we will encounter a FormatException error.

Let’s encapsulate what we want to do into a method:

public static bool ValidateWithNewGuid(string input)
{
    try
    {
        var _ = new Guid(input);
    }
    catch (FormatException)
    {
        return false;
    }

    return true;
}

Here, we establish the ValidateWithNewGuid() method, which accepts an input parameter. Within the method, we attempt to initialize an instance of Guid using new Guid(input) within a try-catch block. If an exception is encountered, it signifies that the input string is not a valid GUID string.

Compare the Performance of GUID Validation Methods

So far, we’ve explored various approaches to validate a string as a GUID. Now, we’re ready to compare the performance of these approaches in terms of speed, memory allocation, and efficiency. To streamline this comparison, we’ll leverage the BenchmarkDotNet library for benchmarking:

| Method                           | Iterations | Mean           | Gen0      | Allocated  |
|--------------------------------- |----------- |---------------:|----------:|-----------:|
| UseValidateWithGuidTryParse      | 1000       |       7.879 us |         - |          - |
| UseValidateWithGuidTryParseExact | 1000       |      10.049 us |         - |          - |
| UseValidateWithRegex             | 1000       |      27.901 us |         - |          - |
| UseValidateWithGuidParse         | 1000       |   1,982.312 us |   19.5313 |   280002 B |
| UseValidateWithNewGuid           | 1000       |   2,015.921 us |   19.5313 |   280002 B |
| UseValidateWithGuidParseExact    | 1000       |   2,285.830 us |   19.5313 |   280002 B |
|                                  |            |                |           |            |
| UseValidateWithGuidTryParse      | 10000      |      80.765 us |         - |          - |
| UseValidateWithGuidTryParseExact | 10000      |     100.864 us |         - |          - |
| UseValidateWithRegex             | 10000      |     196.133 us |         - |          - |
| UseValidateWithGuidParse         | 10000      |  19,848.870 us |  218.7500 |  2800012 B |
| UseValidateWithNewGuid           | 10000      |  20,104.729 us |  218.7500 |  2800012 B |
| UseValidateWithGuidParseExact    | 10000      |  22,864.219 us |  218.7500 |  2800012 B |
|                                  |            |                |           |            |
| UseValidateWithGuidTryParse      | 100000     |     808.876 us |         - |          - |
| UseValidateWithGuidTryParseExact | 100000     |   1,023.358 us |         - |        1 B |
| UseValidateWithRegex             | 100000     |   1,942.818 us |         - |        2 B |
| UseValidateWithNewGuid           | 100000     | 199,408.744 us | 2000.0000 | 28000133 B |
| UseValidateWithGuidParse         | 100000     | 200,091.890 us | 2000.0000 | 28000133 B |
| UseValidateWithGuidParseExact    | 100000     | 229,846.689 us | 2000.0000 | 28000133 B |

It’s clear that techniques employing Guid.TryParse() and Guid.TryParseExact() consistently outperform those relying on regular expressions or manual validation methods like ValidateWithRegex() or ValidateWithNewGuid(), in both execution time and memory usage.

The TryParse() methods notably show significantly lower mean execution times across all test iterations, highlighting their superior performance efficiency. Moreover, they require minimal memory allocation, with almost no Gen0 garbage collections, rendering them not just faster but also more resource-efficient choices for GUID validation tasks. 

Conclusion

In this article, we explored several approaches to validate whether a string represents a GUID in C#. Whether through regular expressions, or built-in parsing methods like Guid.TryParse(), or manual validation based on string length and format, we have a range of tools at our disposal to effectively validate GUIDs. Each approach offers its advantages in terms of readability, performance, and precision, enabling us to choose the most suitable method based on our specific requirements.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!