I suggest you ...

Add non-nullable reference types in C#

Non-nullability checks have to be manually encoded hundreds of times in any large real-world project, and they are not compile-time-enforced. There are code contracts in .Net 4.0, but their usage is still very verbose, and only partly compile-time-enforced.

What I wish is a pendant to the null-lifting operator ?, for instance, !, so that one could write:
void MyMethod(string! s){ /* s cannot be null :) */}

Or, the way ReSharper does it:
void MyMethod([NotNull] string s){ /* s cannot be null :) */}

5,106 votes
Vote
Sign in
Check!
(thinking…)
Reset
or sign in with
  • facebook
  • google
    Password icon
    I agree to the terms of service
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    Marc SigristMarc Sigrist shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

    90 comments

    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      I agree to the terms of service
      Signed in as (Sign out)
      Submitting...
      • Anonymous commented  ·   ·  Flag as inappropriate

        can you imagine the number of back-and-forth conversion between nullable legacy code and non-nullabe ones?

      • Akio TakahashiAkio Takahashi commented  ·   ·  Flag as inappropriate

        I think that it needs to write more code at the calling sites of UI related class.

        UI related classes can't be initialized at constructor in some case or intentionally (for lazy init). So fields in these class are initially null. In other situation, when UI classes represents internal state, fiedls are null as a one state of UI. For example;
        class MyForm : Form {
        private Item currentItem; // Item object if selected.
        }
        In this case, the every code passing currentItem as a Item! type argument needs non-null cast. I guess it feel tired.

        So, I suggest 1 additional syntax: non-null scope. Like this;

        void MyMethod(string s) {
        // s is typed as nullable string here.
        nonnull(s) /* check that s is non null */ {
        // s is treated as a non-null string in this scope.
        // s can be set from string! value or passed to a out/ref string! argument.
        }
        s = null;
        }

      • JustinJustin commented  ·   ·  Flag as inappropriate

        I would go farther, and request an option (per project, or per file) to make the default to disallow null for fields, variables, and parameters. Then introduce a symbol or keyword to make it clear which can be null. Most importantly do it for VB too.
        void foo(Bar br, Baz? bz) {
        String s1 = br.getNotNull();
        String s2 = bz.getNotNull(); // Compile error. bz might be null
        if (bz == null) {
        return;
        }
        String s3 = bz.getNotNull(); // Now it's OK. Compiler knows not null .
        String s4 = bz.getMayBeNull(); // Compile error
        String? s5 = bz.getMayBeNull(); // Now it's OK
        }
        For VB I would use a keyword
        Sub Foo(br As Bar, Optional bz as Baz)
        Optional s5 as String = bz.getMayBeNull()

      • CSharpJohnCSharpJohn commented  ·   ·  Flag as inappropriate

        Agreed. How many times have we written Contract.Requires<ArgumentNullException>(a != null); already?? Beyond a ! operator, we need declarative contracts like:

        public object foo( object o, object o2, int i, int j )
        where o is not null, i >= j fails with ArgumentException // Requires()
        were o2 can be null // Documentation of absence of contract...
        {
        //...
        }
        where result is not null // Ensures
        throws InvalidOperationException; // missing features in contracts: documentation of exceptions

      • Jonathan AllenJonathan Allen commented  ·   ·  Flag as inappropriate

        F# Option types are not a solution to the null problem. In real terms they force you to make two null checks. First you need to check for None/null, then you need to check for Some(null).

        No, we need real non-nullable reference types. And they need a declarative syntax, not that nonsense we got from code contracts.

      • Mauricio SchefferMauricio Scheffer commented  ·   ·  Flag as inappropriate

        Use an option type. It's very simple to implement but you can get it from libraries like Sasa ( https://sourceforge.net/projects/sasa/ ), Functional-dotnet ( http://code.google.com/p/functional-dotnet/ ) or the F# runtime (FSharpx adds sugar for C#/VB.NET: https://github.com/fsharp/fsharpx )
        More importantly, option types are *composable*.
        F# and Scala both support nulls, yet they get rid of 90% of the issues of nulls with option types.

      • Nicolas SévenoNicolas Séveno commented  ·   ·  Flag as inappropriate

        Definitely a must-have in a strongly typed language like C#. I want non-nullable reference types since many years.

        The problem is how to deal with the (huge) existing code base that doesn't use non nullable types ? Any ideas ?

      1 2 3 5 Next →

      Feedback and Knowledge Base