Baral
Baral

Reputation: 3141

C# multiple level generic types in interface

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

Answers (1)

Servy
Servy

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

Related Questions