我的博客
个人资料:
AlanThinker
AlanThinker@stk.me

C#逆变演示

软件开发 发表时间:2016-11-22 更新时间:2016-11-28

逆变是用 in 关键字修饰的.
in 关键字修饰的类型只能用于参数.

协变是用 out 关键字修饰的.          
out 关键字修饰的类型只能用于返回值.              

 协变 out 比较容易理解                
下面是逆变 in  的例子.     
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication21
{
    public interface IPaintable
    {
        ConsoleColor Color { get; set; }
    }

    public class Car : IPaintable
    {
        public ConsoleColor Color { get; set; }
    }

    public interface IBrush<in T> where T : IPaintable
    {
        void Paint(T objectToPaint, ConsoleColor color);
    }
    public class Brush<T> : IBrush<T> where T : IPaintable
    {
        public void Paint(T objectToPaint, ConsoleColor color)
        {
            objectToPaint.Color = color;
        }
    }



    class Program
    {
        static void Main()
        {
            //演示接口逆变
            IBrush<IPaintable> brush = new Brush<IPaintable>();
            IBrush<Car> carBrush = brush;//逆变, 因为brush中的Paint函数可以接受IPaintable类型的参数. 当然也能接受Car类型的参数.
            Car car = new Car();
            carBrush.Paint(car, ConsoleColor.Red);
            Console.WriteLine(car.Color.ToString());

            //演示委托逆变
            // Func的签名为:
            // public delegate TResult Func<in T, out TResult>(T arg)
            var fa_b2 = new Func<A, B2>(delegate(A a)
            {
                return new B2();
            });

            fa_b2(new A2());

            //A2逆变,  因为fa_b2可以接收A类型的参数 当然也能接受A2类型的参数. 所有 fa看转换为fa2.
            //B协变,  因为fa_b2可以返回B2类型的返回值, 返回值当然也能转换为B
            Func<A2, B> fa2_b = fa_b2;
            fa2_b(new A2());

        }
    }

    class A
    {

    }

    class A2:A
    {

    }

    class B
    {

    }

    class B2 :B
    {

    }

}




 
IP Address: 3.142.42.94