How to use variable generics in Dart?

Bloodday

I'm learning dart and flutter, and looked at the Either functionality, but to use it you have to use Left and Right classes nad kinda look not so elegant.

I'm trying to mplement my own OneOf class and it works:

class OneOf<T1, T2> {
  T1? _result1;
  T2? _result2;

  OneOf.formResult(dynamic result) {
    if (result is T1) {
      _result1 = result;
    } else if (result is T2) {
      _result2 = result;
    }
  }

  handle(
      {required void Function(T1?) handleT1,
      required void Function(T2?) handleT2}) {
    if (_result1 != null) {
      handleT1(_result1);
    } else if (_result2 != null) {
      handleT2(_result2);
    }
  }
}

as you can see the implementation uses two generic types, and you can handle the results with the handle function, now I want to have the three generics implementation, but Dart don't allow to have a class with the same name even when they handle a different number of generic parameters (I come from c# and there it is allowed).

is there a way to have a variable amount of generic arguments in the class? or is there another solutin that I'm not seeeing for being new in the language?

for the curious the usage of this class would look like this

var message = "Hello world!!";
var result = OneOf<bool, String>.formResult(mensaje);

result.handle(
  handleT1: (boolResult) {
    print(
        "I have reeived a boolean");
},
                  handleT2: (stringResult) {
    print("I have received the string '$message'");
},
Niko

Sadly there is no way to implement a variable amount of generic arguments.

The only other thing i can think of is using some kind of helper method with dynamic types instead. The downside is that you don't have the static types and have to cast the results.

This is some sort of example code:

typedef Handler = dynamic Function(dynamic);

dynamic oneOf(dynamic result, Map<Type, Handler> handlers) {
  if (handlers.containsKey(result.runtimeType)) {
    return handlers[result.runtimeType]!.call(result);
  } else {
    throw Exception("some error, because no handler was provided for $result");
  }
}

void useOneOf() {
  const String message = "Hello world!!";
  const int number = 123;

  final Map<Type, Handler> handlers = <Type, Handler>{
    String: (dynamic input) => (input as String).toUpperCase(),
    int: (dynamic input) => (input as int) * 2,
  };

  final String result1 = oneOf(message, handlers) as String;
  final int result2 = oneOf(number, handlers) as int;
  print(result1); // "HELLO WORLD!!"
  print(result2); // 246
  final bool exception = oneOf(false, handlers) as bool; // throws exception
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related