协变与逆变
概述
- 协变性: 子类到父类的转换(如:string->object).
- 逆变性: 父类到子类的转换(如:object->string).
- 协变性指定返回类型的兼容性,而逆变性指定参数的兼容性.
委托的协变与逆变
代码示例
协变
逆变
// 基类
class Animal
{
public int Legs = 4;
}
// 派生类
class Dog : Animal
{
}
// Factory 委托
delegate T Factory<out T>();
class Program
{
static Dog MakeDog()
{
return new Dog();
}
static void Main(string[] args)
{
// 创建派生类型的委托
Factory<Dog> dogMaker = MakeDog;
// 派生类型构造的委托转为基类型构造的委托
Factory<Animal> animalMaker = dogMaker;
Console.WriteLine(animalMaker().Legs.ToString());
}
}
接口的逆变与协变
代码示例
协变
逆变
interface IFoo<out T>
{
T GetName();
}
class Foo : IFoo<string>
{
public string GetName()
{
return GetType().Name;
}
}
class Program
{
static void Main(string[] args)
{
IFoo<string> fooStr = new Foo();
IFoo<object> fooObj = fooStr;
// IFoo<object> 需要 object 的返回类型.
// new Fool().GetName() 方法返回类型是 string 类型. string 类型转化为 object 类型.
object memberName = fooObj.GetName();
Console.WriteLine(memberName);
Console.Read();
}
}
interface IFoo<in T>
{
void Print(T content);
}
class Foo : IFoo<object>
{
public void Print(object content)
{
Console.WriteLine(content);
}
}
class Program
{
static void Main(string[] args)
{
IFoo<object> fooObj = new Foo();
IFoo<string> fooStr= fooObj;
// new Fool().Print() 方法输入参数是 object 类型.
// fooStr.Print() 方法输入参数是 string 类型. 隐式将 string 转化为 object.
fooStr.Print("Hello World");
Console.Read();
}
}