C#使用使用接口的泛型进行转换
我有一些实现这些接口的通用接口和类,如下所示:C#使用使用接口的泛型进行转换,c#,generics,interface,instantiation,C#,Generics,Interface,Instantiation,我有一些实现这些接口的通用接口和类,如下所示: interface A<M, N> where M : X<N> where N : Y { } class B<M, N> : A<M, N> where M : X<N> where N : Y { } interface X<M> where M :
interface A<M, N>
where M : X<N>
where N : Y
{
}
class B<M, N> : A<M, N>
where M : X<N>
where N : Y
{
}
interface X<M> where M : Y
{
}
interface Y
{
}
class X1<M> : X<M> where M : Y
{
}
class Y1 : Y
{
}
接口A
其中M:X
N:Y在哪里
{
}
B类:A
其中M:X
N:Y在哪里
{
}
接口X,其中M:Y
{
}
界面Y
{
}
类别X1:X,其中M:Y
{
}
Y1类:Y类
{
}
我知道这似乎是一种非常混乱的做事方式,但我在申请时需要它。我的问题是为什么我不能这样做:
A变量=新B()代码>差异需要明确(需要C#4.0);例如,这使其编译为协变(注意接口中的out
修饰符):
接口A
其中M:X
N:Y在哪里
{
}
接口X,其中M:Y
{
}
但是,请注意,这也将您的界面限制为。。。协方差!例如,您不能有一个Add(M)
方法,因为这需要是contavariant(akain
)。Marc是正确的;只是想给你一些背景知识,解释为什么这不起作用。考虑以下代码的重新命名:
interface IZoo<TCage, TAnimal>
where TCage : ICage<TAnimal>
where TAnimal : IAnimal
{
}
class Zoo<TCage, TAnimal> : IZoo<TCage, TAnimal>
where TCage : ICage<TAnimal>
where TAnimal : IAnimal
{
}
interface ICage<TAnimal> where TAnimal : IAnimal
{
}
interface IAnimal
{
}
class FishTank<TAnimal> : ICage<TAnimal> where TAnimal : IAnimal
{
}
class Fish : IAnimal
{
}
你把长颈鹿围场放进水族馆!在一个您想要的转换是合法的并且IZoo可以有您选择的任何方法的世界中,我们无法维护类型安全
现在,这是唯一危险的,因为IZoo有这样一种方法。如果它没有这样的方法,那么你是对的,这可能是完全安全的。在C#4.0中,我们在语言中添加了一个功能,这样您就可以询问编译器“检查此接口是否可以安全地变为变量”,方法是用“out”注释要协变的类型参数,用“In”注释要逆变的类型参数。如果您这样做,那么编译器将为您检查您想要的差异是否可以被设置为类型安全的。如果不能,则不允许该类型的声明
StackOverflow上通常会出现这样的问题,人们会问为什么这是非法的:
List<Giraffe> giraffes = new List<Giraffe>();
List<Mammal> mammals = giraffes; // illegal
你刚刚在长颈鹿名单上加了一只老虎。同样的道理,只是一个简单得多的例子。嘿,当我尝试这样做时,它说它的C#4.0语言功能出现错误,我该怎么办?@Twinhelix-你使用的是什么版本的Visual Studio,目标是什么平台版本?它在VS2010 Targeting.NET2.0上对我有效。在C#4.0之前。。。在非常有限的情况下,差异有点小。嘿,我正在运行VS2008和.NET3.5。我真的不能改变我的环境设置,有没有办法解决这个问题?我不能升级,因为这是公司的电脑,有很多特权和其他。我希望有一个解决办法:P
Zoo<FishTank<Fish>, Fish> aquarium = new Zoo<FishTank<Fish>, Fish>();
IZoo<ICage<IAnimal>, IAnimal> zoo = aquarium;
interface IZoo<TCage, TAnimal>
where TCage : ICage<TAnimal>
where TAnimal : IAnimal
{
void PutAnimalInCage(TCage cage, TAnimal animal);
}
zoo.PutAnimalInCage(giraffePaddock, giraffe);
List<Giraffe> giraffes = new List<Giraffe>();
List<Mammal> mammals = giraffes; // illegal
mammals.Add(new Tiger());