具有泛型类型的类型接口的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();
}