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