参照其他文章实现了协变和逆变的基本:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace CovarianceAndContravariance
{
class Program
{
#region 委托中的协变与逆变的使用
/*
//协变和逆变主要体现在两个地方:接口和委托,先来看看在委托中如何使用协变和逆变。
//现在我们定义了如下一个表示无参函数的泛型委托Function<T>,类型参数为函数返回值的类型。
//泛型参数之前添加了一个out关键字表示T是一个协变变体。
//那么在使用过程中,基于强类型的委托Fucntion<Bar>实例就可以赋值给基于弱类型的委托Fucntion<Foo>变量。
public delegate T Function<out T>();
static void Main(string[] args)
{
Function<Bar> funcBar = new Function<Bar>(GetInstance);
Function<Foo> funcFoo = funcBar;
Foo foo = funcFoo();
}
static Bar GetInstance()
{
return new Bar();
}
*/
#endregion
#region 逆变委托的用法
/*
public delegate void Operate<in T>(T instance);
static void Main()
{
Operate<Foo> opFoo = new Operate<Foo>(DoSth);
Operate<Bar> opBar = opFoo;
opBar(new Bar());
}
static void DoSth(Foo foo)
{
//Others...
}*/
#endregion
#region 接口中的协变与逆变的使用
//接下来我们同样通过一个简单的例子来说明在接口中如何使用协变和逆变。
//下面定义了一个继承自 IEnumerable<T>接口的IGroup<out T>集合类型,和上面一样,泛型参数T之前的out关键字表明这是一个协变。
//既然是协变,我们就可以将一个基于强类型的委托IGroup<Bar>实例就可以赋值给基于弱类型的委托IGroup<Foo>变量
/*
public delegate void Operate<in T>(T instance);
static void Main()
{
IGroup<Bar> groupOfBar = new Group<Bar>();
IGroup<Foo> groupOfFoo = groupOfBar;
//Others...
}
*/
#endregion
#region 逆变接口
static void Main()
{
IBrush<IPaintable> brush = new Brush<IPaintable>();
IBrush<Car> carBrush = brush;
Car car = new Car();
carBrush.Paint(car, Color.Red);
Console.WriteLine(car.Color.Name);
}
#endregion
}
}
其他所有类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CovarianceAndContravariance
{
public class Bar : Foo
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CovarianceAndContravariance
{
public class Foo
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace CovarianceAndContravariance
{
public interface IBrush<in T> where T : IPaintable
{
void Paint(T objectToPaint, Color color);
}
public class Brush<T> : IBrush<T> where T : IPaintable
{
public void Paint(T objectToPaint, Color color)
{
objectToPaint.Color = color;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CovarianceAndContravariance
{
public interface IGroup<out T> : IEnumerable<T>
{
}
public class Group<T> : List<T>, IGroup<T>
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace CovarianceAndContravariance
{
public interface IPaintable
{
Color Color { get; set; }
}
public class Car : IPaintable
{
public Color Color { get; set; }
}
}
运行结果如下所示: