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 :) */}

6,013 votes
Sign in
Password icon
Signed in as (Sign out)
You have left! (?) (thinking…)
Marc Sigrist shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →


Sign in
Password icon
Signed in as (Sign out)
  • Daniel Babralace commented  ·   ·  Flag as inappropriate

    Microsoft really missed a great opportunity when they introduced structs. Like the company often does, it fixated on the mechanics off programming rather than the concepts. Form follows function, and Microsoft often forgets the function when it gets tunnel vision on the form.

    When Microsoft introduced structs, it added the ? syntax to mark structs as nullable since, being on the stack, structs couldn't be nullable without a new mechanism. And this is where Microsoft made two mistakes.

    First, the application developer should not care at all whether something is on the stack or on the heap. The compiler, or better yet just-in-time compiler, should decide which is more efficient and just make a reference point to one or another. Thus there should be no keyword struct.

    Second and even more importantly, Microsoft didn't have the foresight or the courage to make all references non-nullable unless explicitly opted in by the developer with the ? syntax. Yes, this would break backwards compatibility with existing source code, but it would have been worth it a million times over, especially since a simple app could easily restore backwards compatibility by appending ? to every reference to a non-atomic type. This would make migration to the new platform trivial.

    Imagine if the compiler enforced that no variable and no parameter could be null unless declared with ?. Compile-time enforcement of non-null contracts would elimate countless problems and the declarations would be completely non-intrusive and obvioius. Let's just admit the real problem. Most programmers don't even think about null until a bug occurs. When most programers write

    public String MyMethod (String p1, MyClass p2)

    almost 100% of the time they really mean that the method does not take and does not return any nulls.

    Let's say they did want to take nulls for p2, but not p1 and would not return nulls. See how much clearer the syntax is...

    public String MyMethod (String p1, MyClass? p2)

    And if they wanted to return nulls,

    public String? MyMethod (String p1, MyClass p2)

    Seeing String? as the return type would inform the caller that the method may return nulls and the programmer calling this method is more likely to actually think about the consequences of this.

    Microsoft should really expand ? to be used for all types and make all references without ? to be non-nullable. A simple tool could translate source code to add ? to all references for backwards compatibility, and developers could then remove the unneeded ? at their leisure.

  • Peter commented  ·   ·  Flag as inappropriate

    Maybe I'm oversimplifying things, but IMHO this could be done using an attribute to parameters:

    void MyMethod([NotNull] string myParam)

    If the Compiler sees thiis, it injects something like

    if (value == null)
    throw new ArgumentNullException(nameof(value));

    Or even less verbs, by using something like the (string! myParam) the other poster proposed below.

    And I also would like to see some simple null check. In C++ I can just werite
    if (myPointer)
    for null checks. In C# I always have to write
    if (myRef == null)

    That's the only thing I don't like about C#: It is very verbose and needs a lot of code for simple things. Just look at Swift and how much less code it requires to express the same thing compared to C#.

  • sjb commented  ·   ·  Flag as inappropriate

    I vote for it being a full-blown type. It would be a reference type, analogous to the fact that int? is a value type. So you would have nullable reference types and non-nullable reference types. Like this:

    class BlogEntry {... }
    public void Method( BlogEntry! r) { /* r != null is always true in the body */ }
    BlogEntry myR;
    BlogEntry! yourR = myR; // compile error, no implicit conversion from BlogEntry to BlogEntry!
    BlogEntry! yourR = (BlogEntry!)myR; // compiles, run-time exception thrown if myR is null
    myR = yourR; // compiles, implicit conversion from BlogEntry! to BlogEntry, no runtime exception.

    BlogEntry! hisR = new BlogEntry( ...) // compiles, hisR is definitely assigned
    BlogEntry! hisR = yourR; // compiles, hisR is assigned same non-null value as yourR

    BlogEntry! goodExample( BlogEntry! someR) {
    BlogEntry! hisR;
    if (x == 7) {
    hisR = new BlogEntry(...);
    } else {
    hisR = someR;
    return hisR; // compiles, hisR is definitely assigned before use.

    BlogEntry! badExample( BlogEntry! someR) {
    BlogEntry! hisR;
    if (x == 7) {
    hisR = someR;
    return hisR; // compile error, hisR is not definitely assigned before use.

    BlogEntry!? otherR; // compile error, BlogEntry! is not a value type (also not legal syntax).
    BlogEntry?! thirdR; // compile error, BlogEntry is not a value type (also not legal syntax)
    int?! xx; // compile error, int? is not a reference type (also not legal syntax)
    BlogEntry!! doubleR; // compile error, BlogEntry! is not a nullable reference type (also not legal syntax)

  • .Net is failing commented  ·   ·  Flag as inappropriate

    Some interesting data from the 2017 Stack Overflow survey.

    C# has fallen in popularity from 45% to 34% in just 5 years.

    And Xamarin is one of the most dreaded technologies in the Stack Overflow survey.


    The only really successful language Microsoft ever developed was classic VB, up to its best version ever - the VB6 programming language. They have never achieved the same success since.

  • jaime weise commented  ·   ·  Flag as inappropriate

    how about creating something like using(...) { ... }* that null checks

    with(someVariable) { ... }

  • Jeroen Landheer commented  ·   ·  Flag as inappropriate

    What I do like would be using this for procedure parameters...

    void MyMethod(someType! value){
    /* s cannot be null, so no need for... */
    if (value == null) throw new ArgumentNullException(nameof(value));


    This means the compiler simply inserts that null check code for us, so we won't have to write it all the time.

  • Marc Sigrist commented  ·   ·  Flag as inappropriate

    I am happy to note that this suggestion has been at the very top ever since I wrote it more than five years ago. To understand its popularity, one can simply enter "billion dollar mistake" into any search engine.

    Non-nullability is difficult to retrofit into a language like C#. There are many approaches, who solve the problem to varying degrees. Furthermore, the discussion is tricky, because people easily mix up the semantics of initialization, nullability, and optionality.

    It is all the more exciting that non-null refs are now in the status of prototyping for the next version after C# 7 (see https://github.com/dotnet/roslyn/blob/master/docs/Language%20Feature%20Status.md).

    Last not least: Several modern programming languages already _have_ null-avoidance features, such as F# (https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/values/null-values), Swift (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/swift/grammar/optional-type), or Rust (https://doc.rust-lang.org/std/option/).

  • Marc Lewandowski commented  ·   ·  Flag as inappropriate

    This one is confused right from the title. OP doesn't want non-nullable reference *types*, he wants non-nullable *references*. Confusion throughout the discussion ensues.

    Even that request is problematic: of what use is it? More to the point: are there sufficient cases where a conflict (null reference sent to non-null-reference param) could be detected at compile time to justify the addition of a new language feature?

Feedback and Knowledge Base