文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>C#2.0_1->>泛型

C#2.0_1->>泛型

时间:2011-04-05  来源:乱舞春秋

  1>=泛型概述:

  泛型是一种类型的多态;比如当我们写一个栈或者队列的时候,需要指定其数据类型,int一份代码,string一份代码,object的一份代码,这些代码除了数据类型不同之外其他大部分都是相同的,根据设计模式的思想,抽象出来变化点封装它,共同的部分作为共用的代码。这里的变化点就是类型了,共同部分就是算法相同,所以就把类型抽象化,于是乎泛型问世<个人理解>。

   C#泛型由CLR在运行时支持,这使得泛型可以在CLR支持的各种语言上无缝集合;C#泛型代码在被编译<第一次编译>为IL代码和元数据时【泛型版的IL和元数据】,采用特殊的占位符来表示泛型类型,并用专有的IL指令支持泛型操作,真正的泛型实例化工作发生在JIT编译<第二次编译>时。当JIT编译器第一次遇到这种特殊的IL和元数据时,会利用实际的类型进行替换<泛型类型的实例化>。CLR为所有类型参数是“引用类型”的泛型类型产生同一份代码,而对值类型来说,不同的值类型产生不同的代码,相同的则共用同一份代码。

  C#泛型类型携带有丰富的元数据,因此C#的泛型类型可以应用于强大的反射技术;采用“基类, 接口, 构造器, 值类型/引用类型”的约束方式来实现对类型参数的 “显式约束”,提高了类型的安全性。

  源代码:

MyType
1 public class MyType<T> where T : struct{
2 private T[] _items;
3 public void Add(T itme)
4 {
5 }
6 }

  编译后IL如下:

IL
 1 //泛型类<'1代表元数或者参数数量>
2 .class public auto ansi beforefieldinit MyType`1<valuetype .ctor
3 //注意这里加上了泛型约束<[mscorlib]System.ValueType) T>
4 //表明类型参数是值类型的
5 ([mscorlib]System.ValueType) T>
6 extends [mscorlib]System.Object
7 {
8 } // end of class MyType`1
9 //这是那个私有字段
10 .field private !T[] _items
11
12 //Add方法,类型参数<T>之前有一个感叹号<!>,这是CIL开始支持泛型
13 //后引入的新特性,它指出为类指定的第一个类型参数的存在,表明这是
14 //一个类型参数
15 .method public hidebysig instance void Add(!T itme) cil managed
16 {
17 // 代码大小 2 (0x2)
18 .maxstack 8
19 IL_0000: nop
20 IL_0001: ret
21 } // end of method MyType`1::Add

  除了这些区别外,泛型类和非泛型类的CIL代码并无太大区别。

  2>=泛型类型和泛型方法:

  可以用于泛型的类型有类、接口,结构、委托。

  C#支持泛型方法,但不支持除方法外的其他成员<属性、事件、索引器、构造器、析构器>;泛型方法可以包含在泛型类型中,也可以包含在非泛型类型中<即普通的类型>。

GenericsMehod
 1 public class GenericsMehod
2 {
3 //非泛型类中的泛型方法,参数约束为引用类型
4 //<传入值类型参数将引起编译错误>
5 public int FindItem<T>(T[] items, T item)where T:class
6 {
7 for (int i = 0; i < items.Length; i++)
8 {
9 if (items[i].Equals(item))
10 {
11 return i;
12 }
13 }
14 return -1;
15 }
16 }

调用就不写了,泛型方法支持重载,但是之区别类型参数约束的重载是非法的;也是支持重写的,重写时的类型参数的约束被默认继承,任何的约束的指定都是不必要的,也是不可以指定约束的。

  3>=泛型约束:

  为什么要有约束呢?假如我写了一个泛型类,这个泛型参数调用到CompareTo方法,但是并不是所有的类型参数都有这个方法,假如传入的类型没这个方法,就会引起错误了,所以保证你的代码的健壮的话,加上约束还是很有必要的<就是说传入的类型必须有这个方法才可以编译通过,把错误暴露在编译阶段>。泛型约束支持四种形式的约束【接口约束,基类约束,构造器约束,值类型/引用类型约束】;约束并不是必须的,如果没有指定约束,那么类型参数将只能访问System.Object类型中的公有方法。语法where语句

  上面的类型参数需要一个CompareTo方法就可以用一个接口约束加以实现<public class MyGenerics<T> where T : IComparable{}>;

  基类约束:表是类型参数必须是继承子指定的类型<where T : 基类>;

  构造器约束:只支持无参的构造器约束,就是必须保障参数类型可以调用它的无参构造器<where T : new()>:

  值类型/引用类型约束:只有两种情况了<where T:struct>或者<where T:class>,指定参数类型必须是值类型或者引用类型;

相关阅读 更多 +
排行榜 更多 +
找茬脑洞的世界安卓版

找茬脑洞的世界安卓版

休闲益智 下载
滑板英雄跑酷2手游

滑板英雄跑酷2手游

休闲益智 下载
披萨对对看下载

披萨对对看下载

休闲益智 下载