具有泛型类型的类型接口的C#函数返回实例

具有泛型类型的类型接口的C#函数返回实例,c#,generics,C#,Generics,我有以下资料: public interface IInput { } public interface IOutput { } public interface IProvider<Tin, Tout> where Tin : IInput where Tout : IOutput { } public class Input : IInput {

我有以下资料:

    public interface IInput
    {
    }

    public interface IOutput
    {
    }

    public interface IProvider<Tin, Tout>
        where Tin : IInput
        where Tout : IOutput
    {
    }

    public class Input : IInput
    {
    }

    public class Output : IOutput
    {

    }

    public class Provider : IProvider<Input, Output>
    {

    }
公共接口输入
{
}
公共接口输出
{
}
公共接口IProvider
在哪里输入
卖主:出口在哪里
{
}
公共类输入:IInput
{
}
公共类输出:IOutput
{
}
公共类提供程序:IProvider
{
}
我希望能够获得以下方法来转换结果:

private static IProvider<IInput, IOutput> GetProvider()
{
    return new Provider();
}
private静态IProvider GetProvider()
{
返回新的提供者();
}
我知道类型不同,但它们实现了接口


有什么线索吗?

要想让它起作用,唯一的办法是如果
IProvider
的泛型属性是协变的

public interface IProvider<out Tin, out Tout>
    where Tin : IInput
    where Tout : IOutput
{
}
如果允许我们将
DogCollection
作为
IAnimalCollection
返回,则添加
Cat
完全合法,因为它是
IAnimal
AddAnimal
将是
int-AddAnimal(IAnimal)

通过添加
out
这使得
AddAnimal
方法非法,但现在可以完全安全地说“这组狗被表示为一组动物”,因为现在无法将非狗的动物添加到集合中


要编译上述代码,您必须在两个方面进行权衡。使
GetDogCollection()
不返回接口并删除添加的cat

class Program
{
    static void Main(string[] args)
    {
        IAnimalCollection<IAnimal> animalCollection = GetDogCollection();

        //animalCollection.AddAnimal(new Cat()); //Would get a compiler error if we tried to add a cat to the collection
    }

    private static IAnimalCollection<Dog> GetDogCollection()
    {
        return new DogCollection();
    }
}

我将冒险向你解释另一种方法

也许我弄错了。看起来您正在寻找使用工厂方法创建提供者实例,该方法将在其他地方使用

如果您这样做,您将无法避免此处的显式强制转换:

private static IProvider<IInput, IOutput> GetProvider()
{
    // Explicit upcast
    return (IProvider<IInput, IOuput>)new Provider();
}

.

谢谢,它几乎可以用了。它可以这样投射。但是,我必须从IProvider中删除以下方法:Tout GetOutput(Tin输入)@MatíasFidemraizer他没有使用工厂方法,@ScottChamberlain啊,我明白了。顺便说一句,对我来说,泛型的OP方法听起来很糟糕,因为如果你使用泛型,你需要一个
IProvider
的实例,而不是T,S作为接口。@Baral是的,就像我在回答的下半部分试图解释的那样,如果你想做你想做的事情,权衡是你不能有任何“接受”的方法或属性那个泛型类型。@ScottChamberlain,我复制/粘贴了代码,它没有编译。因为强制转换异常。添加“out”修复了该问题,但破坏了AddAnimal方法:无法将类型“ConsoleInterface.DogCollection”隐式转换为“ConsoleInterface.IAnimalCollection”。存在显式转换(是否缺少强制转换?)
public interface IAnimalCollection<out TAnimal> where TAnimal : IAnimal
{
    TAnimal GetAnimal(int i);
    //int AddAnimal(TAnimal animal); //Can't have methods that take in the type when using "out"
}

class Program
{
    static void Main(string[] args)
    {
        IAnimalCollection<IAnimal> animalCollection = GetDogCollection();

        //animalCollection.AddAnimal(new Cat()); //Would get a compiler error because this method no longer exists.
    }

    private static IAnimalCollection<IAnimal> GetDogCollection()
    {
        return new DogCollection();
    }
}
private static IProvider<IInput, IOutput> GetProvider()
{
    // Explicit upcast
    return (IProvider<IInput, IOuput>)new Provider();
}
public static IProvider<TInput, TOutput> GetProvider<TInput, TOutput>()
    where TInput : IInput 
    where TOutput : IOutput
{
    // Hey!!!!!!!! Do TOutput and TInput of this method are the same as 
    // Provider TOutput and TInput? Who knows, thus, compiler error:
    // Cannot implicitly convert type 'Provider' to 'IProvider<TInput,TOutput>'. 
    // An explicit conversion exists (are you missing a cast?) 
    return new Provider();
}