Search code examples
classflutterdartreturn

How to return multiple types of class types from single generic class in dart flutter?


I have multiple class like this:-

Class A {
  static int xyz = 10;
  int c;
  int d;
  static A getData() {
   // Do something
    return A()..c = xyz*5;
  }

Class B {
  static int abc = 10;
  int c;
  static B getData() {
   // Do something
    return B()..c = xyz*5;
  }

So, here you can see that the the getData() is doing the same thing, but have different return types. Is there any way to avoid duplicate implementation like this, can it be done by defining a single function which can reference the class and have multiple return type?


Solution

  • This has two parts: creating the object, and assigning to a field of the object.

    Creating the object, you are mostly out of luck. The only way to create an object of a specific type in a generic method is by using reflection via dart:mirrors. However, you have indicated that this is for a Flutter project, and Flutter doesn't support reflection, so that isn't an option. The only way you are going to be able to dynamically create an object is to pass in a factory method that the generic method can call to construct the object.

    Assigning to a field of the object is easier, but it requires that you either lose static type checking by using dynamic or by tying your classes together with inheritance. The latter is the preferable choice, but if you are working with a library than it isn't always an option.

    Combining these two things, the code will look like this:

    class Foo {
      static int xyz = 10;
      int c;
    }
    
    class A extends Foo {
      int d;
      
      static A getData() {
        return modifyObject(() => A());
      }
    }
    
    class B extends Foo {
      static B getData() {
        return modifyObject(() => B());
      }
    }
    
    T modifyObject<T extends Foo>(T create()) {
      return create()..c = Foo.xyz * 5;
    }
    

    Before doing this, though, I'd take a look at whether your project actually needs it. If your use case is as simple as your example, I would argue that this level of generalization is overkill and you are hurting your code's readability more than you are helping its modularity.