抗变
C#中泛型接口类型T用 in 关键字修饰代表是可抗变的,即泛型类型T只能用于方法参数输入,并且在实例化接口实现类时,参数可以是实现了泛型类型T的任何派生类。
因为T的派生类包含T的所有内容,所以当T作为方法参数输入时,T的派生类一定满足方法的实现。注意,此时没有多态性,不论以T的何种派生类传递进去,调用的都是T中的实现。
示例:
//父类
class Parent
{
public void Print()
{
Console.WriteLine("父类");
}
}
//子类
class Child : Parent
{
public new void Print()
{
Console.WriteLine("子类");
}
}
//接口
interface IFQ <in T>
{
void Show(T t);
}
//接口实现类
class FQ : IFQ<Parent>
{
public void Show(Parent t)
{
t.Print();
}
}
//测试代码
FQ f = new FQ();
Parent p = new Parent();
Child c = new Child();
f.Show(c);
f.Show(p);
Console.ReadLine();
输出结果如下:
协变
C#中泛型接口类型T用 out 关键字修饰代表是可协变的,即泛型类型T只能用于方法返回值,并且在实例化接口实现类时,参数可以是泛型类型T继承链上的任一上级类。
//父类
class Parent
{
public void Print()
{
Console.WriteLine("父类");
}
}
//子类
class Child : Parent
{
public new void Print()
{
Console.WriteLine("子类");
}
}
//接口
interface IFQ <out T>
{
T Show();
}
//接口实现类
class FQ : IFQ<Child>
{
public Child Show()
{
return new Child();
}
}
//测试
FQ f = new FQ();
Parent p = f.Show();
Child c = f.Show();
p.Print();
c.Print();
Console.ReadLine();
输出结果如下: