w123
w123

Reputation: 111

Why doesn't C# null check work with structs?

I usually check nullable types with if (foo is not null), and afterwards I can use foo like the non-null type. Why doesn't this work with structs? Even the ! operator does not help. Is this a bug or am I missing something? What's the shortest workaround?

Foo? foo = new Foo { a = "foo" }; 
if (foo is not null) {
    Console.WriteLine(foo.a);  // Works, prints "foo"
}

Bar? bar = new Bar { a = "bar" };
if (bar is not null) {
    Console.WriteLine(bar.a);  // Error: Bar? does not contain a definition for "a"
    Console.WriteLine(bar!.a); // Same error
}

class Foo {
    public string a;
}
struct Bar {
    public string a;
}

Upvotes: 1

Views: 965

Answers (3)

Heinzi
Heinzi

Reputation: 172448

Backwards-compatibility.

Nullable value types exist since C# 2.0, and they are implemented differently than nullable reference types (since C# 8.0).

  • int? is a synonym for Nullable<int>, which is a completely different type than int. There is some compiler magic (lifted operators) to make it behave similarly, but Nullable<int> has members that int doesn't have (HasValue, Value) and vice-versa (ToString(string)).
  • string? on the other hand, is of type string, with additional compile-time checks enabled.

Making a null-check on int? allow you to access the underlying int without "unwrapping" it with .Value would have broken tons of existing code.


You can, however, use pattern matching to create a new variable with the underlying type:

int? a = 3;      // implicit conversion from int to Nullable<int>

if (a is int b)
{
    // Use b to access the underlying int here.
}
else
{
    // a was null
}

Upvotes: 4

crankedrelic
crankedrelic

Reputation: 473

Structs are value types and cannot be assigned to null. By declaring the struct as nullable you wrap them in a Nullable<T> struct. You should check the HasValue and Value property of the Nullable<Bar> struct in you case.

        Bar? bar = new Bar { a = "bar" };
        if (bar.HasValue)
        {
            Console.WriteLine(bar.Value.a);
            Console.WriteLine(bar.Value.a);
        }

Upvotes: 2

Sasan
Sasan

Reputation: 21

A struct is a value type so it's never null. You can check the default value for struct

Upvotes: 1

Related Questions