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.
CodePudding user response:
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,
);