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 withMap<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 withMap<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>
.