My feedback

  1. 6,013 votes
    Sign in
    Sign in with: facebook google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    212 comments  ·  Visual Studio IDE » Languages - C#  ·  Flag idea as inappropriate…  ·  Admin →
    gzak commented  · 


    "With the non-nullable strings, the first case (you are sure that string is not null) will be explicitly expressed by the former string having static type string! instead... so you'll just need to propagate the new type, switching from implicit logical condition in your program (some variables here and there may not be null) to explicit ones"

    But I would argue that this is actually a fairly expensive propagation.

    void Foo(string s) { MyMethod(A(s) + B(s) + C(s) + s); }

    Where A, B, and C all accept and return plain string values, not string! values. Does this compile? If so, all the null-checks are runtime checks. If it doesn't compile, how do you fix it? And imagine if you don't own A, B, and C. Now what?

    The thing is, you have to start with the notion of non-nullable types and grow from there. But if you've already grown a large code base without them, it's impractical to introduce them later. That's what's missing here...

    gzak commented  · 

    Fundamentally, you can't enforce this kind of thing entirely at compile time in the same way you can't entirely catch division-by-zero errors at compile time (at least, not pleasantly).

    An important thing to notice here is that while it looks like you've solved the nullability problem for MyMethod, you've actually just pushed it up to all of its callers.

    Suppose a caller has a regular string, not a string!, can they pass it to MyMethod? If so, that's automatically a runtime check.

    Or do they in turn also need a string! first? But now the caller has to change. And god forbid the caller's string in turn came from one of its arguments, or from the result of some other method call, suddenly it becomes exponentially difficult for the caller of MyMethod to secure a string! to pass in... That would be the only way to 100% enforce this at compile time.

    And if there's a "converter" from string to string!, that converter is again a runtime check, automatically.

    Basically, to enforce this entirely at compile time you'd need to exponentially ripple the string! change all the way up the various call stacks (and sometimes down some other branches). It would be similar with trying to catch division-by-zero, where you can imagine something like this:

    int MyDivider(int y, int~ x) { /* int~ means non-zero int, so x cannot be 0 */ }

    So while I very much like the idea of non-nullability in theory, in practice it wouldn't really work, especially without breaking compatibility with a ton of existing code. It would really only work if you were designing a language from scratch, one which only has value types. But C# isn't that language, if you'd like that you should use F# instead.

    That's why I'm more in favor of introducing a ?. operator. It's comparatively simple, and doesn't break anything. Less is more...


Feedback and Knowledge Base