C#协变与逆变

参照其他文章实现了协变和逆变的基本:

 

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; }
    }
}

运行结果如下所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值