It's not as common of a problem in C# to just initialize the array to the elements you need. Most arrays in regular code you will see will have their elements initialized or materialized from LINQ anyway.
I agree that NRTs are "leaky" (and wish they did it better) but I do not run into the issues you do it seems and they are a massive productivity improvement, their static-analysis-based nature also helps with not dealing with some of the ceremony caused by e.g. Option<T> in Rust.
On the snippet above - it will print true only when called inside the constructor, when the field has not been yet assigned to. It will print false otherwise. I do not see this as an issue, although it is indeed subtle.
And to be clear, I'm not saying that nullability checking is a bad idea! On the contrary, it's great. It's especially great when the type system doesn't lie to you (i.e. if something being not nullable actually means that it can never be null), but even partial enforcement is better than nothing.
However, the OP to whom I responded specifically complained about "idea of the zero values for uninitialized struct fields" in Go, and then in the same breath mentioned "language that works, like C#" - which is rather ironic given that C# does, in fact have this exact thing, and I tried to explain why it needs it.
That aside, with respect to default(T), the other problem is arrays. If T is non-nullable and you ask for a new T[1], what should the value of the element be? C# lies and allows it to be null even for non-nullable reference types, which means that (new string[1])[0].ToString() is an NRE with no compiler diagnostic even with #nullable enabled. In C++, you actually cannot do this at all if T doesn't have a default constructor, but this then means that the language needs stuff like in-place new and explicit destructor calls to actually make a generic dynamic array possible to implement.