0

I know there is a such a thing as Guid? and Nullable<Guid>. I have this code and it compiles:

public Contact GetContact(Guid contactId)
{
    if (contactId == null)
    {
        throw new ArgumentNullException(nameof(contactId));
    }

    return _communicationsDbContext.Set<Contact>().Find(contactId);
}

Can "contactId == null" ever be true?

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
Meca
  • 149
  • 2
  • 20
  • 1
    No, it cannot. In fact, when you compile you get a warning telling you so – Camilo Terevinto Jan 17 '19 at 00:13
  • 1
    By the way, `Guid?` is a shorthand to `Nullable` – Camilo Terevinto Jan 17 '19 at 00:16
  • 1
    What happened when you tried to set `contactId = null;`? – Rufus L Jan 17 '19 at 00:26
  • I tried what Gnbrkm41 said. The compiler just removes that line of code. – Meca Jan 17 '19 at 00:51
  • I am asking if a Guid can ever be null? (I am not asking how to make it nullable). The reason I am asking is because the compiler isn't complaining about the code. – Meca Jan 17 '19 at 00:53
  • `I am asking if a Guid can ever be null?` The answer is No (as shown in the duplicate). `The reason I am asking is because the compiler isn't complaining about the code.` Well, I can't ever be George Clooney - but that doesn't mean you can't **ask** whether I am George Clooney. `if (contactId == null)` is technically valid code. It is silly (since it will never be `true`). But it is not invalid. Which is why it compiles for you. – mjwills Jan 17 '19 at 03:28
  • Reason `if (contactId == null)` compiles is because Guid implements custom equality operator (`public static bool operator == (Guid left, object right)`). Operator too is a method; think of it as `Guid.op_Equality(contactId, (object)null)`. `struct`s do not implement a default equality operator, so for `struct`s that do not implement custom == would not compile as there's no such method. – Gnbrkm41 Jan 17 '19 at 11:43
  • One reason someone might implement equality operator that returns true when compared with null could be to write their own Nullable. Nullable is a struct, therefore it cannot be null; but it can be compared to null and returns true if the object represents null. (Though I don't know why someone would do it if there's already a built-in type with syntactic sugar) – Gnbrkm41 Jan 17 '19 at 11:53
  • Side note: comparison between Nullable instance and null gets substituted to property call nullable.HasValue in compile time. It's more of a language feature rather than custom equality operator; Nullable<> does not implement equality operator. – Gnbrkm41 Jan 17 '19 at 12:02
  • Found this: https://stackoverflow.com/questions/2177850/guid-null-should-not-be-allowed-by-the-compiler – Gnbrkm41 Jan 17 '19 at 12:21

3 Answers3

3

System.Guid is a struct, which cannot be null as it is not a reference type. I believe that for known struct types that implement custom equality operator (e.g. int, Guid etc) the compiler will substitute the null comparison with false. (Hence the whole comparison and throw statement will disappear)

For the struct types that do not implement custom equality operator, the code simply won't compile.

Nonetheless, it is unnecessary.

See: https://sharplab.io/#v2:EYLgtghgzgLgpgJwDQxASwDYB8ACAGAAhwEYBuAWACgcBmIgJgIGECBvKgzounAFgICyACgDiAVzQATAgHMJkgJRsOXVWgBmBIXKkEAvHoIA7MRgxKYACwQB7AO7G4DgIII5YOEZgA5UxgCiAB4AxnAADjBoNkZCChSUqgC+VIlAA===

public void M(Guid guid)
{
    if (guid == null) throw new ArgumentNullException();
}

will be compiled to:

// Methods
    .method public hidebysig 
        instance void M (
            valuetype [mscorlib]System.Guid guid
        ) cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 1 (0x1)
        .maxstack 8

        IL_0000: ret
    } // end of method C::M

As you can see, the first instruction in the method is return.

Gnbrkm41
  • 238
  • 3
  • 9
2

System.Guid is a struct, and structs can never be null.

Instead, you may wish to check that it is not the "zero" Guid:

x != Guid.Empty
sdgfsdh
  • 33,689
  • 26
  • 132
  • 245
1

A Guid is a value type so it can't be null. One way to check is:

if (contactId == Guid.Empty)

or

 contactId == default(Guid)
Gauravsa
  • 6,330
  • 2
  • 21
  • 30