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


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

  • 相关阅读:
    [LeetCode] 101. 对称二叉树
    [LeetCode] 394. 字符串解码!!!!
    USACO Ordered Fractions
    USACO The Castle
    遇到的Mysql的一个坑
    USACO-palsquare 遇到的一个坑
    大整数相乘
    vs2012扩展
    JS实现文字倒计数
    jqAutoComplete 和 knockout
  • 原文地址:https://www.cnblogs.com/xtxtx/p/9128216.html
Copyright © 2020-2023  润新知