Vishnubly
Vishnubly

Reputation: 729

How to perform runtime type casting in dart

I was having an error like List<dynamic> is not a subtype of List<double> but here the problem is here List<double> is determined on runtime, I am doing something like this:-

extension Ext<T> on List<T> {
  List<T> deepClone() {
    List<T> res = [];
    for (var value in this) {
      if (value is List) {
        res.add(value.deepClone() as T); //List<dynamic> is not the subtype of List<double>
      } else {
        res.add(value);
      }
    }
    return res;
  }
}

Now for example, if we call this method like this:-

List<List<double>> values = [[3, 4], [4, 1, 2]];
List<List<double>> cloneValues = values.deepClone(); //gives an error List<dynamic> is not the subtype of List<double>
List<List<List<String>>> strValues = [[["hello"], ["world", "hi"]], [["cat"]]];
List<List<List<String>>> clonedStrValues = strValues.deepClone() //gives and error List<dynamic> is not the subtype of List<String>

I researched a lot and found I cannot cast it on runtime, and the problem here is I need this function for different types of lists, so I cannot create a different function for each type either, can anyone help me?

Upvotes: 0

Views: 496

Answers (1)

Michael Horn
Michael Horn

Reputation: 4089

The problem is that deepClone is not itself a generic function, which means that it can't recursively return different types - it can only return the type defined on the extension.

Therefore, instead of making the extension generic, make deepClone generic:

extension on List {
  List<T> deepClone<T>() {
    List<T> res = [];
    for (var value in this) {
      if (value is List) {
        res.add(value.deepClone() as T);
      } else {
        res.add(value);
      }
    }
    return res;
  }
}

Also, it was probably just a typo, but in the code you posted, you iterated over res in your for loop, which of course will always be empty, since it was just created ;). Instead, the for loop should iterate over this.

Upvotes: 1

Related Questions