学习笔记: 泛型应用、原理、协变逆变、泛型缓存

1. c# 是怎么支持泛型的?

   泛型 =  编译器支持+JIT支持
    控制台 编译生成 exe或dll, 然后 exe被点击时, 由 JIT(即时编译器 Just-In-Time) 即时编译变成机器码
    编译器针会把 泛型 编译成占位符, JIT 编译时, 会把它替换为真实类型

  image


2. 泛型方法的效率怎么样? 

generic≈原生代码>obj(装箱拆箱)

public class Monitor
     {
         public static void Show()
         {


             Stopwatch watch = new Stopwatch();
             watch.Start();

            for (int i = 0; i < 100000000; i++)
             {
                 ShowInt(i);
             }
             watch.Stop();
             Console.WriteLine("ShowInt: {0}",watch.ElapsedMilliseconds);

            watch.Restart();
             for (int i = 0; i < 100000000; i++)
             {
                 ShowObj(i);
             }
             Console.WriteLine("ShowObj: {0}", watch.ElapsedMilliseconds);

            watch.Restart();
             for (int i = 0; i < 100000000; i++)
             {
                 ShowGeneric<int>(i);
             }
             Console.WriteLine("ShowGeneric: {0}", watch.ElapsedMilliseconds);
             watch.Stop();

        }

        public static void ShowInt(int param){
             //do nothing
         }

        public static void ShowGeneric<T>(T param)
         {
             //do nothing
         }

        public static void ShowObj(object param)
         {
             //do nothing
         }
     }

image

3. 逆变与协变   参考链接http://www.cnblogs.com/yukaizhao/archive/2011/10/27/xiebian-nibian.html

一句话: 如果一个方法要接受Dog参数,那么另一个接受Animal参数的方法肯定也可以接受这个方法的参数,这是Animal向Dog方向的转变是逆变。

           如果一个方法要求的返回值是Animal,那么返回Dog的方法肯定是可以满足其返回值要求的,这是Dog向Animal方向的转变是协变。

class Program
     {
         static void Main(string[] args)
         {
             //协变 如果一个方法要求的返回值是Animal,那么返回Dog的方法肯定是可以满足其返回值要求的,这是Dog向Animal方向的转变是协变
             ICustomerListOut<Person> customerListOut1 = new CustomerListOut<Person>();
             ICustomerListOut<Person> customerListOut2 = new CustomerListOut<Man>();

            //逆变 如果一个方法要接受Dog参数,那么另一个接受Animal参数的方法肯定也可以接受这个方法的参数,这是Animal向Dog方向的转变是逆变
             ICustomerListIn<Person> customerListIn1 = new CustomerListIn<Person>();
             ICustomerListIn<Man> customerListIn2 = new CustomerListIn<Person>();

        }
     }

    /// <summary>
     /// out 协变 只能作为返回类型
     /// </summary>
     /// <typeparam name="T"></typeparam>
     public interface ICustomerListOut<out T>
     {
         T Get();
         //void Show(T t); //T不能作为传入参数
     }

    /// <summary>
     /// 类 没有协变/逆变的概念, 只有接口/委托支持协变
     /// </summary>
     /// <typeparam name="T"></typeparam>
     public class CustomerListOut<T> : ICustomerListOut<T>
     {
         public T Get()
         {
             return default(T);
         }
     }

    /// <summary>
     /// 逆变 in 只能作为传入类型
     /// </summary>
     /// <typeparam name="T"></typeparam>
     public interface ICustomerListIn<in T>
     {
         //T Get();//T不能作为返回参数
         void Show(T t);
     }

    public class CustomerListIn<T> : ICustomerListIn<T>
     {
         public void Show(T t)
         {
             throw new NotImplementedException();
         }
     }


    public class Person
     {
         public int Id { get; set; }
     }

    public class Man : Person
     {
         public string Name { get; set; }
     }

原文地址:https://www.cnblogs.com/xtxtx/p/9128216.html