❔ Difference string and string?
string? t = null; // no warning
string t2 = null; // warning
Console.WriteLine(t);
Console.WriteLine(t2); //behaves same
10 Replies
?
denotes nullabilityYeah but looks like t2 is also null ?
Well, it's... tricky
Prepare for a story lol
I knew it was comming :p
Used to be, that all reference types (types based on
class
es) were nullable by default. Meaning, if you had a class Foo {}
you could do Foo f = null
without any issue.
Value types meanwhile (types based on struct
s) were not nullable by default, so the same would throw an exception
All primitive types (int, bool, float, etc) in C# are implemented as value types
Except string
That's because value types are stored differently in memory than reference types. That has some benefits, but one drawback is limited size. And since strings can get quite large, it made sense to implement them as reference types, but provide a lot of value-type-like semantics. Like value equality instead of reference equality
One thing that was left for reasons unbeknownst to me, is that string
was nullable by default, like the rest of reference tyopes
Cue .NET 6 and nullable reference types
That made it so, by default, the compiler will warn you about trying to assign null to reference types
As opposed to actual value types, though, they decided to not make it a full-on exception, for backwards compatibility reasons
And there isn't really anything that stops you from treating reference types as nullable by default in the first place. Nothing really changed for them, except the warnings being added
So... that makes it so that despite string
being nullable under the hood, since it's a reference type, you get a warning because of nullable reference types that came in .NET 6
It's a weird limbo. Reference are kinda-nullable-but-kinda-not
Now, you can make such warnings about nullability turn into errors, if you want to be strict. By adding <WarningsAsErrors>Nullable</WarningsAsErrors>
to PropertyGroup
in your .csproj
fileInteresting, I know strings are some special kind in C#. Not rly new to C# but since these warnings came with nullable stuff I got confused lately on wheter to use or not use nullable types. it made no sense to me that if it behaves the same that it gives a warning
But I guess string? > string if it can be nullable yh?
Yeah
It compiles to
Nullable<string>
Cool, cool
Only value types get wrapped into Nullable<T> which is a different type that spoofs null checks and will prevent compilation if you do say
int a = (int?)1
Reference types get labeled with an attribute and only lead to warnings though it still compile as the actual type is the same
Both use the question mark suffix but are two different concepts.
Spoofs the value as in Nullable is a struct so it can't be null. It has an internal flag for if the value is meant to be null and comparisons are based on that. If it were actually nullable, the HasValue property couldn't workWas this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.
Was this issue resolved? If so, run /close
- otherwise I will mark this as stale and this post will be archived until there is new activity.