iDecode
iDecode

Reputation: 28926

Directly passing a List to a method fails but wrapping it into a variable works

Some magic is going on which is shaking my basics:

void main() {
  method(['1', '2']); // fails

  final list = ['1', '2'];
  method(list); // works
}

void method(List<Object> objects) {
  List<String> strings = objects;
}

Can anyone explain the reason behind this magic?

Upvotes: 0

Views: 58

Answers (1)

lrn
lrn

Reputation: 71723

Dart type inference infers missing types for an expression based on the expectations of the surrounding context and on the types of the sub-expressions. It gives more weight to the "context type".

In the first case method(['1', '2']);, the context type of the list literal is List<Object>. That's the parameter type of method. Since the only type missing from the list literal is the list element type itself, and List<Object> is what is being asked for, the compiler infers method(<Object>['1', '2']);. That creates a List<Object>, passes it to method, which then tries to down-cast that to List<String>. That fails because a List<Object> is not a List<String>, not even if all its members are (currently) strings.

In the second case, final list = ['1', '2']; there is no context type. So, lacking that, the element type is inferred from the actual elements. Since they are all strings, the compiler infers final list = <String>['1', '2'];. That List<String> is then passed to method as a List<Object> (that's fine because a List<String> is a List<Object>), and it's then down-cast back to List<String>, which works because it is one.

So, the difference is in the context type of the list literal.

Upvotes: 2

Related Questions