标签:code 引用 commons gen jasmine name 属性 ctr 一个
一、泛型引入
需求:传入一个类型(整型/日期/字符串或其他),打印出它的类型和内容。
1.初级版
1 public class CommonMethod 2 { 3 /// <summary> 4 /// 打印int值 5 /// </summary> 6 /// <param name="iParameter"></param> 7 public static void ShowInt(int iParameter) 8 { 9 Console.WriteLine("This is {0},parameter={1},type={2}", 10 typeof(CommonMethod).Name, iParameter.GetType().Name, iParameter); 11 } 12 13 /// <summary> 14 /// 打印string值 15 /// </summary> 16 /// <param name="sParameter"></param> 17 public static void ShowString(string sParameter) 18 { 19 Console.WriteLine("This is {0},parameter={1},type={2}", 20 typeof(CommonMethod).Name, sParameter.GetType().Name, sParameter); 21 } 22 23 /// <summary> 24 /// 打印DateTime值 25 /// </summary> 26 /// <param name="dParameter"></param> 27 public static void ShowDateTime(DateTime dParameter) 28 { 29 Console.WriteLine("This is {0},parameter={1},type={2}", 30 typeof(CommonMethod).Name, dParameter.GetType().Name, dParameter); 31 } 32 }
typeof和gettype的区别
调用
1 static void Main(string[] args) 2 { 3 DateTime dt = DateTime.Now; 4 int i = 5; 5 string test = "test"; 6 object o = new object(); 7 CommonMethod.ShowDateTime(dt); 8 CommonMethod.ShowInt(i); 9 CommonMethod.ShowString(test); 10 }
2.升级版
1 /// <summary> 2 /// 打印object值 3 /// 1.object是一切类型的基础 4 /// 2.通过集成,子类拥有父类的一切属性和行为 5 /// </summary> 6 /// <param name="o"></param> 7 public static void ShowObject(object oParameter) 8 { 9 Console.WriteLine("This is {0},parameter={1},type={2}", 10 typeof(CommonMethod).Name, oParameter.GetType().Name, oParameter); 11 }
调用
1 DateTime dt = DateTime.Now; 2 int i = 5; 3 string test = "test"; 4 object o = new object(); 5 CommonMethod.ShowObject(dt); 6 CommonMethod.ShowObject(i); 7 CommonMethod.ShowObject(test); 8 CommonMethod.ShowObject(o);
缺点:如果传递的是值类型,会装箱拆箱
二、泛型来喽
定义泛型
1 public class GenericMethod 2 { 3 /// <summary> 4 /// 方法名字后面带上尖括号 类型参数 5 /// T可以换成其他任何未定义的名称,但是不要用关键字、类名等等 6 /// 来自 .net framework2.0 CLR升级的 7 /// 解决相同内容/操作,对于不同参数的问题 8 /// 9 /// 延迟声明,声明方法的时候没有指定参数类型,而是等到调用的时候指定 10 /// 延迟思想:推迟一切可以推迟的 11 /// 12 /// 编译的时候 类型参数编译为占位符 `(1旁边英文输入状态) 13 /// 程序运行的时候,jit即时编译替换为真实类型 14 /// 15 /// 16 /// </summary> 17 /// <param name="o"></param> 18 public static void Show<T>(T tParameter) 19 { 20 Console.WriteLine("This is {0},parameter={1},type={2}", 21 typeof(CommonMethod).Name, tParameter.GetType().Name, tParameter); 22 } 23 }
调用
1 GenericMethod.Show<DateTime>(dt); 2 GenericMethod.Show(dt);//不指定类型参数,编译器自动推算(编译器的语法糖) 3 GenericMethod.Show<int>(i); 4 GenericMethod.Show<string>(test); 5 GenericMethod.Show<object>(o);
三、消耗时间对比
1 using System; 2 using System.Diagnostics; 3 4 namespace MyGeneric 5 { 6 public class Monitor 7 { 8 public static void Show() 9 { 10 Console.WriteLine("******************Monitor****************"); 11 int iValue = 123456; 12 long commonSecond = 0; 13 long objectSecond = 0; 14 long genericSecond = 0; 15 16 { 17 Stopwatch watch = new Stopwatch(); 18 watch.Start(); 19 for (int i = 0; i < 100000000; i++) 20 { 21 ShowInt(iValue); 22 } 23 watch.Stop(); 24 commonSecond = watch.ElapsedMilliseconds; 25 } 26 27 { 28 Stopwatch watch = new Stopwatch(); 29 watch.Start(); 30 for (int i=0;i<100000000;i++) 31 { 32 ShowObject(iValue); 33 } 34 watch.Stop(); 35 objectSecond = watch.ElapsedMilliseconds; 36 } 37 { 38 Stopwatch watch = new Stopwatch(); 39 watch.Start(); 40 for (int i = 0; i < 100000000; i++) 41 { 42 Show(iValue); 43 } 44 watch.Stop(); 45 genericSecond = watch.ElapsedMilliseconds; 46 } 47 Console.WriteLine("commonSecond={0},objectSecond={1},genericSecond={2}", 48 commonSecond, objectSecond, genericSecond); 49 Console.Read(); 50 } 51 52 53 public static void ShowInt(int iParameter) 54 { 55 //do nothing 56 } 57 58 59 public static void ShowObject(object oParameter) 60 { 61 //do nothing 62 } 63 64 public static void Show<T>(T tParameter) 65 { 66 //do nothing 67 } 68 } 69 }
调试启动的时间如下,可以看出泛型执行的时间是最短的。
如果更换顺序,将执行泛型的方法放到第一位的话,会出现泛型时间和普通时间一样,甚至还会比它耗费时间长的情况。
ctrl+F5启动时间对比如下(这一块不懂,为什么普通方法要比泛型的时间快呢)
四、泛型类
1 using System; 2 3 namespace MyGeneric 4 { 5 //泛型类 6 public class GenericClass<W,Jasmine,Apple>//参数类型可以随便指定,意思就是相当于在这个类中定义了一个w的类型 7 { 8 public void Show(W w) { } 9 public Jasmine Get() 10 { 11 return default(Jasmine); 12 } 13 } 14 /// <summary> 15 /// 泛型接口 16 /// </summary> 17 /// <typeparam name="T"></typeparam> 18 public interface IStudy<T> 19 { 20 T Study(T t); 21 } 22 public delegate Everything GetHandler<Everything>();//泛型委托 23 24 /// <summary> 25 /// 普通类 26 /// </summary> 27 public class Child 28 //: GenericClass<string,int,string> //指定类型参数后即可继承 29 //:GenericClass<W, Jasmine, Apple> 这种写法是错误的,普通类不能直接继承泛型类 30 //:IStudy<T> 普通类不能直接实现泛型接口 31 : IStudy<string> 32 { 33 public string Study(string t) 34 { 35 throw new NotImplementedException(); 36 } 37 } 38 39 40 public class GenericChild<W,Jasmine, Apple> 41 //: GenericClass<W,Jasmine,Apple> //泛型类可以直接继承泛型类 42 //public class GenericChild<W, Jasmine>//等于声明了两个局部类型 W和Jasmin 43 //: GenericClass<W, Jasmine, string> 44 :IStudy<W> //泛型类不能直接实现泛型接口 45 { 46 public W Study(W t) 47 { 48 throw new NotImplementedException(); 49 } 50 } 51 52 }
五、泛型约束
1.所需模型
1 using System; 2 3 namespace MyGeneric 4 { 5 public class Model 6 { 7 public class People 8 { 9 public int Id { get; set; } 10 public string Name { get; set; } 11 public void Hi() 12 { 13 } 14 } 15 16 public interface ISports 17 { 18 void PingPang(); 19 } 20 21 public interface IWork 22 { 23 void Work(); 24 } 25 26 public class Chinese : People,ISports,IWork 27 { 28 public void Tradition() 29 { 30 Console.WriteLine("谦虚"); 31 } 32 public void SayHi() 33 { 34 } 35 36 public void PingPang() 37 { 38 throw new NotImplementedException(); 39 } 40 41 public void Work() 42 { 43 throw new NotImplementedException(); 44 } 45 } 46 47 public class Sichuan : Chinese 48 { 49 public string Panda { get; set; } 50 public void Huoguo() 51 { 52 Console.WriteLine("吃火锅啦"); 53 } 54 } 55 } 56 57 }
2.泛型约束(基类约束)
1 using System; 2 using static MyGeneric.Model; 3 4 namespace MyGeneric 5 { 6 public class Constraint 7 { 8 /// <summary> 9 /// 有约束才有自由,有权利就得有义务 10 /// 11 /// 1.基类约束,就可以访问基类的方法和属性(基类/子类) 12 /// </summary> 13 /// <typeparam name="T"></typeparam> 14 /// <param name="tParameter"></param> 15 public static void Show<T>(T tParameter) where T : People //基类约束 16 { 17 Console.WriteLine("This is {0},parameter={2},type={1}", 18 typeof(CommonMethod).Name, tParameter.GetType().Name, tParameter); 19 20 Console.WriteLine(tParameter.Id); 21 Console.WriteLine(tParameter.Name); 22 tParameter.Hi(); 23 } 24 } 25 }
调用
1 People people = new People() 2 { 3 Id = 1, 4 Name = "张三" 5 }; 6 Chinese chinese = new Chinese() 7 { 8 Id = 2, 9 Name = "李四" 10 }; 11 Sichuan sichuan = new Sichuan() 12 { 13 Id = 3, 14 Name = "小红" 15 }; 16 17 Constraint.Show(people); 18 Constraint.Show(chinese); 19 Constraint.Show(sichuan);
3.泛型约束(接口约束)
1 public static void ShowSports<T>(T tParameter) where T : ISports //基类约束 2 { 3 Console.WriteLine("This is {0},parameter={2},type={1}", 4 typeof(CommonMethod).Name, tParameter.GetType().Name, tParameter); 5 6 tParameter.PingPang(); 7 }
调用和上面的相同,实现了该接口的类,可直接当做参数传入。
4.其他泛型约束写法
1 public static T Get<T>() 2 //where T:class //引用类型约束 3 //where T:struct//值类型约束 4 where T:new() //无参数构造函数约束 5 { 6 T t = new T(); 7 return default(T); 8 }
六、协变
1.相关模型(Sparrow是Bird的子类)
1 public class Bird 2 { 3 } 4 5 public class Sparrow : Bird 6 { 7 }
2.
1 Bird bird1 = new Bird(); 2 //左边父类,右边子类 3 Bird bird2 = new Sparrow(); 4 Sparrow sparrow1 = new Sparrow(); 5 List<Bird> birdList1 = new List<Bird>(); 6 //List<Bird> bird3 = new List<Sparrow>(); //不是父子关系,没有继承关系 7 8 List<Bird> birdlist2 = new List<Sparrow>().Select(s => (Bird)s).ToList();
3.查看IEnumerable定义,可以看到有一个关键字out
4.下面可实现左边是父类,右边是子类
1 //协变 2 IEnumerable<Bird> birdList4 = new List<Bird>(); 3 IEnumerable<Bird> birdList5 = new List<Sparrow>();//协变
5.具体应用
1 /// <summary> 2 /// out协变 只能是返回值 3 /// 协变逆变只存在于接口或者委托 4 /// </summary> 5 /// <typeparam name="T"></typeparam> 6 public interface ICustomerListOut<out T> 7 { 8 T Get(); 9 //void Show(T t); // 此处错误,T不能作为传入参数 10 } 11 12 /// <summary> 13 /// 类没有协变逆变 14 /// </summary> 15 /// <typeparam name="T"></typeparam> 16 public class CustomerListOut<T> : ICustomerListOut<T> 17 { 18 public T Get() 19 { 20 return default(T); 21 } 22 }
调用
1 ICustomerListOut<Bird> customerList = new CustomerListOut<Bird>(); 2 ICustomerListOut<Bird> customerList1 = new CustomerListOut<Sparrow>(); //协变
七、逆变
1.定义
1 public interface ICustomerListIn<in T> 2 { 3 //T Get(); 4 5 void Show(T t); 6 } 7 8 /// <summary> 9 /// 逆变 只能作为参数传入 10 /// </summary> 11 /// <typeparam name="T"></typeparam> 12 public class CustomerListIn<T> : ICustomerListIn<T> 13 { 14 //T Get(); //不能作为返回值 15 16 public void Show(T t) 17 { 18 } 19 }
2.调用
1 //逆变 2 ICustomerListIn<Sparrow> customerList2 = new CustomerListIn<Sparrow>(); 3 ICustomerListIn<Sparrow> customerList3 = new CustomerListIn<Bird>(); //左边是子类的时候,右边可以是父类 4 5 ICustomerListIn<Bird> birdList6 = new CustomerListIn<Bird>(); 6 birdList6.Show(new Sparrow()); 7 birdList6.Show(new Bird());
八、协变逆变混合应用
1.定义
1 public interface IMyList<in inT, out outT> 2 { 3 void Show(inT t); 4 outT Get(); 5 outT Do(inT t); //out只能是返回值 in只能是参数 6 } 7 8 public class MyList<T1, T2> : IMyList<T1, T2> 9 { 10 11 public void Show(T1 t) 12 { 13 Console.WriteLine(t.GetType().Name); 14 } 15 public T2 Get() 16 { 17 Console.WriteLine(typeof(T2).Name); 18 return default(T2); 19 } 20 public T2 Do(T1 t) 21 { 22 Console.WriteLine(t.GetType().Name); 23 Console.WriteLine(typeof(T2).Name); 24 return default(T2); 25 } 26 }
2.调用
1 IMyList<Sparrow, Bird> myList1 = new MyList<Sparrow, Bird>(); 2 IMyList<Sparrow, Bird> myList2 = new MyList<Sparrow, Sparrow>(); //协变 3 IMyList<Sparrow, Bird> myList3 = new MyList<Bird, Bird>(); //逆变 4 IMyList<Sparrow, Bird> myList4 = new MyList<Bird, Sparrow>(); //逆变
九、泛型缓存
不太懂,有时间再好好研究下(捂脸......)
标签:code 引用 commons gen jasmine name 属性 ctr 一个
原文地址:https://www.cnblogs.com/jas0203/p/10383606.html