Sample source code:
void main() {
final func = () => petOwners.selectMany(
(petOwner) => petOwner.pets, (petOwner, petName) => {petOwner: petName});
print(func.runtimeType);
}
final petOwners = [
PetOwner('Higa', ['Scruffy', 'Sam']),
PetOwner('Ashkenazi', ['Walker', 'Sugar']),
PetOwner('Price', ['Scratches', 'Diesel']),
PetOwner('Hines', ['Dusty']),
];
class PetOwner {
String name;
List<String> pets;
PetOwner(this.name, this.pets);
}
extension IEnumerable<TSource> on Iterable<TSource> {
Iterable<TResult> selectMany<TCollection, TResult>(
Iterable<TCollection> Function(TSource) collectionSelector,
TResult Function(TSource, TCollection) resultSelector) {
return null;
}
}
Output:
() => Iterable<Map<PetOwner, dynamic>>
That is, instead of getting the result () => Iterable<Map<PetOwner, String>>
I get a rather strange result of the form () => Iterable<Map<PetOwner, dynamic>>
.
In this rather simple case, the Dart compiler is not able to infer the type "TCollection".
I can’t understand what is the reason. The code is quite simple. Easier nowhere.
Nevertheless, the result is very poor. Is this a bug in the compiler or is it done according to the language specification?
If this meets the specifications, then why was this decision made? Are there really any advantages from this (in such minimization and simplification)?
P.S.
The same simplest code written in C# works without problems.
EDIT:
The problem in that the compiler cannot infer the type "TCollection" from this code (Iterable<TCollection> Function(TSource) collectionSelector
):
(petOwner) => petOwner.pets
The compiler should consider this code as the following:
() => (PetOwner) => List<String>
But the compiler recognizes this code like this:
() => (PetOwner) => dynamic