The question mark to denote a nullable type is inherited from the .net framework days. You'd use that to mark a value type as nullable, which is syntactic sugar for Nullable<T>. Internally, that object stores a bool for IsNull and it packs your value into an Object. When dealing with value types, this results in a copy-by-value every time you access it, which is bad in most cases.
I don't like this solution because it reuses something that I've learned is a Bad Thing. Though I'm sure the current implementation just stores a reference to the object in question.
But fundamentally, I think nulls are a good thing. Null carries information. If C/++ can handle null pointers for the last 40 years, I think C# can handle it. But then again, maybe this is a problem domain that I've just never encountered. The only problems I have with nulls is around ergonomics, but the null coalescing and safe access operators solve that for the most part. Maybe it's a bigger problem at scale, I really wouldn't know. At the scale I operate at, non-nullable reference types causes more headache than it solves problems
I don't like this solution because it reuses something that I've learned is a Bad Thing. Though I'm sure the current implementation just stores a reference to the object in question.
But fundamentally, I think nulls are a good thing. Null carries information. If C/++ can handle null pointers for the last 40 years, I think C# can handle it. But then again, maybe this is a problem domain that I've just never encountered. The only problems I have with nulls is around ergonomics, but the null coalescing and safe access operators solve that for the most part. Maybe it's a bigger problem at scale, I really wouldn't know. At the scale I operate at, non-nullable reference types causes more headache than it solves problems