泛型

.NET进阶篇-语言章-1-Generic泛型深入

匿名 (未验证) 提交于 2019-12-03 00:13:02
内容目录 一、概述 二、泛型的好处 三、泛型使用 1、泛型方法 2、泛型类、泛型接口 四、泛型的功能 1、泛型中的默认值 2、约束 3、协变逆变 5、泛型委托 4、泛型缓存 五、总结 一、概述 泛型我们一定都用过,最常见的List<T>集合。.NET2.0开始支持泛型,创建的目的就是为了 不同类型创建相同的方法或类,也包括接口,委托的泛型 。比如常见的ORM映射,一个方法通过传入不同的类,返回不同的类实例,再调用时才确定参数类型。 我们知道想要一个类相同名称的方法,如果仅参数类型不同,那么要重载。重载会有很多冗余的代码。在.NET1.0时代也可以不用重载,那就是参数类型直接用Object类型,那么任何类型都能传进去了,但是会有装箱拆箱操作,影响性能。 二、泛型的好处 值类型和引用类型的装箱拆箱消耗。 值类型分配在线程栈上,引用类型分配在堆上,只把指针放在栈上 。如图所示,如果把int类型1装箱,就要把1拷贝到堆中,就会有内存的交换。以前的ArrayList就是类型不安全的,需要频繁的进行装拆箱操作,Add元素的时候全部装箱object,取的时候要拆箱,性能损失比较大。 泛型的效率等同于硬编码的方式,就是和你很多功能相同的类效率差不多。泛型每个类型只实例化一次,下面泛型缓存会详细解读下。先简单介绍下CLR的运行原理(详细在CLR章节)以了解泛型的原理机制。

C#泛型集合之――列表

匿名 (未验证) 提交于 2019-12-03 00:13:02
列表基础   1.列表概述:列表与哈希集合不同之处在于,它的元素可以重复。(更接近逻辑上的数组,而哈希集合更接近于数学上的集合)   2.创建及初始化:         (1)List<类型> 列表名 =new List<类型>();         (2)List<类型> 列表名 =new List<类型>(){值};         (3)List<类型> 列表名 =new List<类型>(数组名);   3.基础操作:       (1)添加单个元素:列表名.Add(所添加元素);       (2)添加多个元素:列表名.AddRange(所添加元素的数组名);       (3)插入一个元素:列表名.Insert(参数一:插入位置,参数二:所要插入的元素); //插入位置从1开始 //可以用foreach 遍历       (4)插入一组元素:列表名.InsertRang(参数一:插入位置,数组);       (5)删除一个元素:列表名.Remove(元素); //注意若有多个同值元素,仅删除第一个       (6)通过下标删除一个元素: 列表名.RemoveAt(元素下标);       (7)通过下标删除多个元素:列表名.RemoveRange(参数一:从哪开始,参数二:个数)       (8)列表可以用 列表名[下标] 进行调用元素,而哈希集合不能。     

泛型排序 (VB.NET)

匿名 (未验证) 提交于 2019-12-03 00:08:02
泛型排序 (VB.NET) Module _4_Generic_Demo Sub Main() Dim list As New List(Of Person) list.AddRange(New Person() {New Person("Ken", 36), New Person("Allen", 56), New Person("Mary", 28)}) Print2(list) list.Sort() Print2(list) list.Sort(New NameComparer) Print2(list) End Sub Sub Print(ByVal list As List(Of Integer)) For Each i As Integer In list Console.WriteLine(i) Next Console.WriteLine("--------------------------------------------------") End Sub Sub Print2(ByVal list As List(Of Person)) For Each i As Person In list Console.WriteLine(i.Name & " : " & i.Age) Next Console.WriteLine("-----------------

TypeScript泛型

匿名 (未验证) 提交于 2019-12-03 00:05:01
泛型的概念 指不预先确定的数据类型,具体的类型要在使用的时候才能确定。咋一听,是不是觉得JavaScript本身就是这样?这是由于理解有误。前面说“在使用的时候确定”,而非在程序执行的时候确定。 泛型函数 现在有个需求:一个被定义的函数原本输入字符串输出字符串,现在想让它同时支持输入输出字符串数组,如何实现? 1.通过函数重载 // 函数调用时依照声明的顺序进行匹配 function log ( value : string ): string ; function log ( value : string []): string []; function log ( value : any ): any { console . log ( value ); return value ; } log ( "abc" ); log ([ "10" , "abc" ]); 2.使用联合参数 function logs ( value : string | string []): string | string []{ return value } 以上两种都OK,但是不够简洁,不够灵活。下面使用泛型。 function log1 < T >( value : T ): T { return value } 等价于 let log1 = < T >( value : T ) => {

TS-泛型

匿名 (未验证) 提交于 2019-12-03 00:02:01
TSѧϰ 泛型 基本使用 //定义一个普通的函数 这样 只能返回一个number类型的数值 如果希望能传入一个任意类型的参数,则可以使用any function Hello(num:number):number{ return num } //但是使用any的话 就失去了校验参数的意义 所以 我们就使用泛型 function Hello1(str:any):any{ return str } //泛型的基本写法 function Hello2<T>(arg:T):T{ return arg } let output = Hello2<string>("hello") //定义泛型的好处就是 可以在使用的时候去规定传进去的参数 而不是在定义方法的时候规定 alert(output) 泛型的应用 function Hello3<T>(str:T[]):T[]{ return str } let list:Array<string> = Hello3<string> (['a','b','c']); for(let i=0;i<list.length;i++){ alert(list[i]) } 泛型类型 interface Hello4{ <T>(arg:T):T; } function myHello<T>(arg:T):T{ return arg; } let HM:Hello4

泛型

匿名 (未验证) 提交于 2019-12-03 00:00:02
public class Pair<T> { … } public static <K> Pair<K> create(K first, K last) { … } public class Pair<T,K> { … } Java的泛型(Generic)是采用擦拭法(Type Erasure)实现的。 编译把 视为Object 编译器根据 实现安全的强制转型 我们写的是 public static void main(String[] args) { Pair<String> pair = new Pair<>("xiao","ming"); String first = pair.getFirst(); } 实际上编译器处理的是 public static void main(String[] args) { Pair pair = new Pair("xiao","ming"); String first = (String)pair.getFirst(); } 不能是基本类型,例如int Object字段无法持有基本类型 无法取得带泛型的Class(返回的永远的同一个Class) 如: Pair<String>.class 无法判断带泛型类型的类型,例如: x instanceof Pair<String> 不能实例化 T 类型 如: new T(); 可以继承自泛型类:

泛型和隐式转换

匿名 (未验证) 提交于 2019-12-02 23:57:01
def main(args: Array[String]): Unit = { // 通过传递的参数自动推断泛型类型 (参数中用到了所有的泛型) val s1 = new Student("丽萨",1) // 直接指定泛型类型 val s2 = new Student[String,Int]("明明",2) // 指定参数类型的父类为泛型 val s3 = new Student[Any,Any]("小刚",3) } // 泛型类 class Student[T,S](info1: T, info2: S){ println(info1,info2) } def fun[T](field: T): Unit ={ println(field) } <: 指明上界,表达了泛型的类型必须是"某种类型"或某种类型的"子类" >: 指明下界,表达了泛型的类型必须是"某种类型"或某种类型的"父类" def main(args: Array[String]): Unit = { up[C2](new C2) // 报错! 超出上边界 // up(new C1) // 必须需要指定[class], new C3会自动转为匹配的的父类 down[C3](new C3) } // 指定泛型上限 def up[T <: C2](field: T): Unit = { println("Up") } /

泛型

匿名 (未验证) 提交于 2019-12-02 23:49:02
1.1 泛型概述 1.2 使用泛型的好处 不使用泛型 使用泛型 . 1.3 定义和使用有泛型的类 泛型是一个未知的数据类型,当我们不确定什么什么数据类型的时候,可以使用泛型 泛型可以接收任意的数据类型,可以使用Integer,String,Student... 创建对象的时候确定泛型的数据类型 private E name; public E getName(){return name;} public void setName(E name){this.name = name;} } public class DemoGenericClass{ public static void main(String[] args){ //不写泛型默认为Objectl类型 GenericClass gc1 = new GenericClass(); gc.setName("只能是字符串"); //创建GenericClass对象,泛型使用Integer类型 GenericClass<Integer> gc2 = new GenericClass<>(); gc.setName(1); Integer name = gc2.getName(); System.out.println(name); } } 1.4 定义和使用含有泛型的方法 定义含有泛型的方法

遍历list集合泛型为map

匿名 (未验证) 提交于 2019-12-02 23:49:02
public class ListAddMap { public static void main( String args[] ) { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); Map<String, Object> map = new HashMap<String, Object>(); Student stu1 = new Student( "\u5f20\u4e09", 26, 180 ); Student stu2 = new Student( "\u674e\u56db", 28, 175 ); map.put( "stu1", stu1 ); map.put( "stu2", stu2 ); list.add( map ); System.out.println( "方法一 :" ); for( int i = 0; i < list.size(); i++ ) { System.out.println( list.get(i) ); } System.out.println( "方法二 :" ); for( Map<String, Object> mapList : list ) { for( String key : mapList.keySet() ) {

雷林鹏分享:Lua for 循环

匿名 (未验证) 提交于 2019-12-02 23:47:01
  Lua 编程语言中 for 循环语句可以重复执行指定语句,重复次数可在 for 语句中控制。   Lua 编程语言中 for语句有两大类::   数值for循环   泛型for循环   数值for循环   Lua 编程语言中数值for循环语法格式:   for var=exp1,exp2,exp3 do   <执行体>   end   var 从 exp1 变化到 exp2,每次变化以 exp3 为步长递增 var,并执行一次 "执行体"。exp3 是可选的,如果不指定,默认为1。   实例   for i=1,f(x) do   print(i)   end   for i=10,1,-1 do   print(i)   end   for的三个表达式在循环开始前一次性求值,以后不再进行求值。比如上面的f(x)只会在循环开始前执行一次,其结果用在后面的循环中。   验证如下:   #!/usr/local/bin/lua   function f(x)   print("function")   return x*2   end   for i=1,f(5) do print(i)   end   以上实例输出结果为:   function   1   2   3   4   5   6   7   8   9   10   可以看到 函数f(x)只在循环开始前执行一次。