3

I am trying to create a class "CombinedResource" that will contain 2 properties, each is of the type "Resource".

Now the Resource class is as follows:

class Resource<T>{
  final T? data;
  Resource({this.data});
}

And the CombinedResource class is as follows:

class CombinedResource<T1 extends Resource<Ta>, T2 extends Resource<Tb>, Ta, Tb>
 {
  final T1? resourceA;
  final T2? resourceB;
  
  const CombinedResource._({
    this.resourceA,
    this.resourceB,
  });

  factory CombinedResource.create(
    Resource<Ta> rA,
    Resource<Tb> rB,
  ) =>
      CombinedResource._(
        resourceA: rA,
        resourceB: rB,
      );
}

Now, the problem is that the compiler is giving me an error on the factory method:

The argument type 'Resource<Ta>' can't be assigned to the parameter type 'T1?'.

I tried changing the CombinedResource class to be as follows:

class CombinedResource<Ta,Tb>
{
  final Resource<Ta>? resourceA;
  final Resource<Tb>? resourceB;
  
  const CombinedResource._({
    this.resourceA,
    this.resourceB,
  });

  factory CombinedResource.create(
    Resource<Ta> rA,
    Resource<Tb> rB,
  ) =>
      CombinedResource._(
        resourceA: rA,
        resourceB: rB,
      );
}

This caused another problem, where I was unable to create an instance of CombinedResource:

 CombinedResource.create(
                  Resource(data:"sdc"), Resource(data:"sdc"));

  The argument type 'String' can't be assigned to the parameter type 'Resource<String>?'.

What am I doing wrong here?

Update: The second approach is working fine.

1
  • 1
    I can't reproduce any problem with your second version. Commented Dec 19, 2021 at 9:23

1 Answer 1

2

Your first attempt failed because you do:

  factory CombinedResource.create(
    Resource<Ta> rA,
    Resource<Tb> rB,
  ) =>
      CombinedResource._(
        resourceA: rA,
        resourceB: rB,
      );

but CombinedResource._ expects arguments of type T1 and T2. You've specified that T1 is derived from Resource<Ta>, which means that an instance of a T1 must be an instance of a Resource<Ta>. The reverse, however, is not true: not every Resource<Ta> is necessarily a T1. Therefore a Resource<Ta> is not implicitly assignable to a T1. (Downcasts are potentially unsafe.)

I don't know why you inexplicably made your factory constructor use a different signature from your private constructor, but it'd work if you fixed it to use matching types:

  factory CombinedResource.create(
    T1 rA,
    T2 rB,
  ) =>
      CombinedResource._(
        resourceA: rA,
        resourceB: rB,
      );
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.