Home > OS >  Compatibility of argument types
Compatibility of argument types

Time:12-04

I wonder if my thinking is correct, or I'm making some big mistake. Let's have simple code:

class A { String a = "a"; }

class B extends A { String b = "b"; }

void goofy(Map<String, A> map) {
  A? item = map["b1"];
  print(item?.a);
}

void croc(dynamic map) {
  final A? item = (map as Map<String, A>)["b1"];
  print(item?.a);
}

void frape(dynamic map) {
  final A? item = (map["b1"]) as A;
  print(item?.a);
}


void main() {
  Map<String, B> mapInst = {"b1":B()};
  goofy(mapInst);
  croc(mapInst);
  frape(mapInst);
  
  Map<String, A> mapInst2 = {"b1":A()};
  goofy(mapInst);
  croc(mapInst);
  frape(mapInst);
}

All functions goofy , croc and frape works as expected. However I'm not so sure about signatures. Do Map<String,A> is compatible with Map<String,B> since B inherits from A? Or this is just a side effect, and in reality it matters that base type is Map and generics are not taken under consideration? Which syntax is recommended for situation when I want to pass Maps which can have A or B type in generic signature? Maybe just plain Map?

CodePudding user response:

Do Map<String,A> is compatible with Map<String,B> since B inherits from A

Yes, if B did not inherit from A, the code would not compile.

Which syntax is recommended for situation when I want to pass Maps which can have A or B type in generic signature?

As you said in one of your comments, you can use the extends keyword on a type argument

void myFunction<T extends A>(Map<String, T> map) { ... }

CodePudding user response:

If a class Derived derives from a class Base, then Generic<Derived> will be considered to be a subtype (a more specific type) of Generic<Base>.

Do Map<String,A> is compatible with Map<String,B> since B inherits from A?

Depends on what you mean by "compatible". Map<String, B> is substitutable for Map<String, A>. That is, you may safely pass a Map<String, B> where a Map<String, A> is expected. However, the reverse is not safe (and therefore would require an explicit cast).

Which syntax is recommended for situation when I want to pass Maps which can have A or B type in generic signature?

I would use Map<String, A>.

  • Related