Search code examples
dartconstructorinitialization

Initializing a Class used in the Constructor of another Class


I'm using one class inside of another and having a hard time with initialization. This code won't compile because it says "The default value of an optional parameter must be constant" and MyClass(x:0) is not a constant.

class UpperClass {
  int a;
  MyClass b; 
  UpperClass({this.a = 0, this.b = MyClass(x:0)});
  } 

class MyClass {
  int x;
  MyClass({required this.x});
}

Changing the constructor to this eliminates compiler errors:

UpperClass({a, b}) : this.a = a, this.b = b;

But the documentation says the preferred, equivalent is:

UpperClass({this.a, this.b});

but here the compiler complains that a and b are null.

I'd like to understand what's really going on here. Is it ok to use the constructor that compiles? Is there a better practice?


Solution

  • Your issue is that the value you want as default, MyClass(x: 0), is not a constant.

    You can fix this in one of two ways.

    The first is to make it constant, which means making the MyClass constructor const, which again requires all instance variable of MyClass to be final. Then do , this.b = const MyClass(x: 0), at it will be allowed.

    If that's too restrictive on MyClass, if it really cannot be a class with a const constructor, you cannot use a default value to initialize it. Then you should make the parameter nullable, because an optional parameter must be nullable or have a default value (aka., it must have a default value, and if you don't write one, the default value will be null, which must then be a valid value).

    That means changing the UpperClass constructor to:

      UpperClass({this.a = 0, MyClass? b}) : b = b ?? MyClass(x:0);
    

    If you do want to use the same instance of MyClass every time, even if it isn't const, you can create a default instance:

      UpperClass({this.a = 0, MyClass? b}) : b = b ?? _defaultB;
      static final MyClass _defaultB = MyClass(x:0);