Home > Enterprise >  The argument type 'ListOf5' can't be assigned to the parameter type 'ListOf5
The argument type 'ListOf5' can't be assigned to the parameter type 'ListOf5

Time:02-24

I need to implement an abstract class function, which own a an specific data type. But I need inside my logic layer to make the attribute which is going to be passed as a dynamic data type. But when i Pass it to the function, i am sure that its data type will be as needed. So, i type (product.value.pickedImages) as ListOf5) . But it does an Exception.

The Abstract Class Code Is:

 Future<Either<FireStoreServerFailures, List<String>>> uploadProductImages(
      {required ListOf5<File> images});

The Implementation Code Is:

Future<Option<List<String>>> _uploadImagesToFirestorage() async {
    return await productRepo
        .uploadProductImages(
            images: (product.value.pickedImages) as ListOf5<File>) // Exception
  }

The Exception Is:

The argument type 'ListOf5 < dynamic>' can't be assigned to the parameter type 'ListOf5 < File>'.

CodePudding user response:

You are trying to cast the List from List<dynamic> to List<String>. Instead, you should cast each item, using something like this:

void main() {
  List<dynamic> a = ['qwerty'];
  print(List<String>.from(a));
}

Not sure about the implementation of this ListOf5 though...

CodePudding user response:

The cast (product.value.pickedImages) as ListOf5<File> fails. It fails because product.value.pickedImages is-not-a ListOf5<File>, but instead of ListOf5<dynamic> (which may or may not currently contain only File objects, but that's not what's being checked).

Unlike a language like Java, Dart retains the type arguments at run-time(it doesn't do "erasure"), so a ListOf5<dynamic> which contains only File objects is really different from a ListOf5<File> at run-time.

You need to convert the ListOf5<dynamic> to a ListOf5<File>.

How to do that depends on the type ListOf5, which I don't know. For a normal List, the two most common options are:

  • (product.value.pickedImages).cast<File>(). Wraps the existing list and checks on each read that you really do read a File. It throws if you ever read a non-File from the original list. Perfectly fine if you'll only read the list once.
  • List<File>.of(product.value.pickedImages). Creates a new List<File> containing the values of product.value.pickedImages, and throws if any of the values are not File objects. Requires more memory (because it copies the list), but fails early in case there is a problem, and for small lists, the overhead is unlikely to be significant. If you read the resulting list many times, it'll probably be more efficient overall.

If the ListOf5 class provides similar options, you can use those. If not, you might have to build a new ListOf5 manually, casting each element of the existing ListOf5<dynamic> yourself. (If the ListOf5 class is your own, you can choose to add such functionality to the class).

  •  Tags:  
  • dart
  • Related