Search code examples
nulldart-null-safety

How are null objects functions accessible when the object is null in null safety


In my understanding a null object is an object that has no referenced value? Like a box that doesn't exist and any functions on that object are inaccessible.

Now in Null safety, more specifically Dart you can access the functions (in an extension) on a null object and get the result without having to do null checks like ? or !

void main() {
  String? a;
  String b;
  
  a = "a";
  b = "b";
  
  print(a.test2);
  a = null;
  print(a.test2);// Here we don't need to do null checks on this object but we can still safely access "test2"
  print(b.test2); 
}

extension Test on String? { // Notice: The extension is on a nullable String
  String get test2 => "$this test";
}

Is my understanding of null objects, null and void(Pun intended) or is there something I have missing in my understanding of null objects?

You can play around with this on https://dartpad.dev/?id=c655e00920d2078654a9277287e3e450


Solution

  • A variable that does not actually point to an instance of it's type is null.

    You cannot do anything with a null value, other than check whether it is null or not.

    Your extension is valid, because it is just syntactic sugar for having a normal function with this variable as it's first parameter. Dart hides that fact a little too well, other languages make it clearer what actually happens under the hood.

    So the extension you wrote is basically a static method saying "if you pass me a nullable string, I will return a constant". And yes, that is possible. It is a little messy to explain, so let me explain with a normal method instead of a getter:

    extension Test on String? { // Notice: The extension is on a nullable String
      String test2() { return "$this test"; }
    }
    

    This is nothing new. You could have written:

    String test2(String? value) { return "$value test"; }
    

    And it would be clear why this works: you never access value at all. An extension is not magic. It is just your compilers way of saying: you know what? Calling test2(a); all the time looks really uncool and it's hard to get auto-completion on this, so let me help you. If you call that an "extension", I will allow you to call it like this: a.test2();. It's literally the same characters in a different order. That is all the "extension" does: it allows you to call the method with the same syntax as a class method, instead of as a free function with your value as the first parameter.

    So yes, you can pass a nullable variable to a method that accepts a nullable parameter. Inside that method, you will have to do null checks again, if you want to do anything with that variable.