Reputation: 3141
Saying I have the following interfaces
using System;
public interface IInput
{
}
public interface IOutput<Shipper> where Shipper : IShipper
{
}
public interface IShipper
{
}
public interface IProvider<TInput, TOutput>
where TInput : IInput
where TOutput : IOutput<IShipper>
{
}
I am able to create the following classes:
public class Input : IInput
{
}
public class Shipper : IShipper
{
}
public class Output : IOutput<Shipper>
{
}
I tried multiple ways to create a class implementing IProvider with no luck?
Ex:
public class Provider : IProvider<Input, Output>
{
}
Error: The type 'Output' cannot be used as type parameter 'TOutput' in the generic type or method 'IProvider<TInput,TOutput>'. There is no implicit reference conversion from 'Output' to 'IOutput<IShipper>'
or
public class Provider : IProvider<Input, Output<IShipper>>
{
}
Error: The non-generic type 'Output' cannot be used with type arguments
How Can I do this?
Upvotes: 2
Views: 996
Reputation: 203802
You're trying to treat the generic argument Shopper
in IOutput
as if it's covariant. You need to explicitly state that that generic argument is covariant when declaring the interface:
public interface IOutput<out Shipper> where Shipper : IShipper
{
}
(Notice the out
keyword.)
Then the code compiles.
Note that after making this change you will no longer be able to use the generic type argument Shipper
as parameters to any members of that interface; if it would be used in such a manor then the interface wouldn't be conceptually covariant.
You can actually simplify the code down a bit to remove some of the issues not relevant to this problem. It all boils down to being able to do the following:
IOutput<Shipper> output = new Output();
IOutput<IShpper> = output;
That conversion is only valid if IOutput
is covariant with respect to its generic argument.
Upvotes: 4