Home > Software engineering >  How to cast an object with a generic type
How to cast an object with a generic type

Time:04-20

I have this small code snippet:

class A<T> {
  A(this.a);
  
  final T a;
}


void main() {
  final a = A(true);
  print(a);
  print(a as A<bool>);
  
  final b = A<Object>(true);
  print(b);
  print(b as A<bool>);  
}

I'm receiving the object b from a library/API which is a A<Object> (and I don't have control over it), but I know it is actually a A<bool> in my specific case. I'm trying to cast it to A<bool> (as in my code snippet with b). But I get an error saying that A<Object> is not a subtype of A<bool>.

Here are the logs from the code snippet pasted above:

Instance of 'A<bool>'
Instance of 'A<bool>'
Instance of 'A<Object>'
Uncaught Error: TypeError: Instance of 'A<Object>': type 'A<Object>' is not a subtype of type 'A<bool>'

How can I cast b (a A<Object>) into a A<bool>?

CodePudding user response:

The following code can cast it. dont know if it works in your case.

var c = A<bool>(b.a as bool);
/// OR
extension Cast on A<Object> {
  A<bool> cast() => A<bool>(a as bool);
}

CodePudding user response:

How can I cast b (a A<Object>) into a A<bool>?

You can't. They're not the same type.

b was constructed as an A<Object>, so its runtime type is A<Object>, regardless of whether b.a happens to be referring to a bool. A cast with as changes the static (known to the compiler) type of an object, but you cannot change an object's runtime type. If you want an object with a different runtime type, you must construct a separate object.

Let's consider a slightly different example:

class C<T> {
  T value;

  C(this.value);
}

C<T> is the same thing as A<T> except that its member is not final. If casting an object with a runtime type of C<Object> to C<bool> were allowed, then we could have the following:

final c = C<Object>(true);
final casted = c as C<bool>; // Should this be allowed?
c.value = 'Hello world!'; // Legal since `c.value` is of type `Object`.
bool someBool = casted.value; // ???

Arguably the case for casting A is different; A's member is final and therefore wouldn't lead to the above scenario. However, I'd expect that that kind of exception would add a lot of complexity and possibly could make things even more confusing.

Also see: https://stackoverflow.com/a/67223011/

  • Related