【重点】泛型:有了泛型,就可以创建独立于被包含类型的类和方法了。我们不必给不同的类型编写功能相同的许多方法和类,只创建一个方法或类即可,以下是泛型的特点:性能、类型安全性、二进制代码重用、代码的扩展、命名约定

  1、性能:空间的泛型和非泛型集合类 System.Collections 和 System.Collections.Generic

    值类型存储在栈上,引用类型存储在堆上。 C# 类 是引用类型,结构是值类型。 .NET很容易把值类型转换为引用类型,所以可以在需要对象(对象是引用类型)的任何地方使用值类型。例如,int 可以赋予一个对象。从值类型转换为引用类型成为装箱。如果方法需要把一个对象作为参数,同时传递一个值类型,装箱操作就会自动进行。另一方面,装箱的值类型可以使用拆箱操作转换为值类型。在拆箱时,需要使用类型强制转换运算符。

  [延伸]装箱和拆箱

【装箱和拆箱】
下面可以像处理对象那样处理字面值:
string s=10.ToString();//隐式转换 C#通过拆箱(unboxing)和装箱(boxing)可以把值类型转换为引用类型,并把引用类型转换回值类型。
【装箱】:用于描述把一个值类型转换为引用类型。运行库会为堆上的对象创建一个临时的引用类型“箱子”。
int myIntNumber=20;
object myObject=myIntNumber; //显示转换 【拆箱】用于描述相反的过程,其中以前 装箱的值类型 强制转换回 值类型。这里使用术语 “强制转换”,是因为这种转换时显示进行的。
int myIntNumber=20;
object myObjet=myIntNumber;//把 myIntNumber 进行装箱
int mySecondNumber=(int)myObject;//拆箱 强制转换 ★只能对以前装箱的变量进行拆箱,当myObject 不是装箱后的int 型时,如果执行最后一行就会抛出异常。 !!这里有一个警告,在拆箱时,必须非常小心,确保得到的值变量有足够的空间存储拆箱的值中的左右字节。例如 C# 的int 有 32位 ,所以把 long 值(64位) 拆箱为 int 时,会导致一个 InvalidCastException 异常。
long myLongNumber=32323131;
object myObject=myLongNumber;
int myIntNumber=(int)myObject;

  例 System.Collection 中的 ArrayList类中进行的拆箱装箱操作 ArrayList存储对象,Add()方法定义为需要把一个对象作为参数。

 var list=new ArrayList();
list.add();//进行装箱,把值类型转换为引用类型
int i1=(int)list[];//拆箱 foreach(int i2 in list)
{
Console.WriteLine(i2);//进行拆箱
}

  >>装箱和拆箱很容易使用,但性能损失比较大,遍历许多项时尤其如此。

  

  System.Collections.Generic 中的 List<T> 类不使用对象,而是在使用时定义类型。在下面的例子中,List<T> 类的泛型定义为 int ,所以int 类型在JIT 编译器动态生成的类中是 int,不再进行拆箱装箱

 var list=new ArrayList<int>();
list.Add();//不在进行装箱
int i1=list[]; //不再进行拆箱 转换
foreach(int i2 in list)
{
Console.WriteLine(i2);
}

  2、类型安全

   与ArrayList 类一样,如果使用对象,就可以在这个集合中添加任意类型。下面的例子在ArrayList类型的集合中添加一个整数、一个字符串和一个MyClass 类型的对象;

    

 var list=new ArrayList();

 list.Add();
list.Add("GellW");
list.Add(new MyClass()); //当使用下面的foreach 来迭代时,并不是所有元素都可以强制转换为 int 就会抛出一个运行异常
foreach(int i2 in list)
{
Console.WriteLine(i2);
}

  若在泛型类 List<T> 中泛型类型 T 定义了允许使用的类型。有了 比如 List<int> 的定义,就只能把整数类型添加到集合中。编译器就不会编译这段代码,因为 Add 的参数无效

  

 var list=new ArrayList<int>();
list.Add();
list.Add("Geell");//编译时错误
list.Add(new MyClass());//编译时错误。

  【扩展】

  

var : 该变量需要根据初始化表达式来推断变量的类型,而且只能是局部变量。在声明时必须同时赋值。

  3、二进制代码的重用

 var list1=new List<int>();
list1.Add(); var list2=new List<stirng>();
list2.Add("Stringhisdm"); var list3=new List<MyClass>();
list3.Add(new MyClass());

  4、命名约定

    • 泛型类型的名称用字母T 作为前缀。
    • 如果没有特殊要求,泛型类型允许使用任意类替代,且只是用了一个泛型类型,就可以用字符T作为泛型类型的名称。    
    •  public class List<T>{}
      
       public class LinkedList<T>{}
    • 如果泛型类型有特定的要求(例如,它必须实现一个接口或派生自基类),或者使用了两个或多个泛型类型,就应给泛型类型使用描述性的名称: 
    •  public delegate void EventHandle<TEventArgs>(object sender,TEventArgs e);
      
       public delegate TOutput Converter<TInput,TOutput>(TInput from);
      
       public class SortedList<TKey,TValue>{}

C#高级编程笔记 Day 5, 2016年9月 13日 (泛型)的更多相关文章

  1. 2016年12月13日 星期二 --出埃及记 Exodus 21:8

    2016年12月13日 星期二 --出埃及记 Exodus 21:8 If she does not please the master who has selected her for himsel ...

  2. 2016年11月13日 星期日 --出埃及记 Exodus 20:4

    2016年11月13日 星期日 --出埃及记 Exodus 20:4 "You shall not make for yourself an idol in the form of anyt ...

  3. 2016年10月13日 星期四 --出埃及记 Exodus 18:24

    2016年10月13日 星期四 --出埃及记 Exodus 18:24 Moses listened to his father-in-law and did everything he said.于 ...

  4. C#高级编程笔记 Delegate 的粗浅理解 2016年9月 13日

    Delegate [重中之重] 委托 定义一:(参考)http://www.cnblogs.com/zhangchenliang/archive/2012/09/19/2694430.html 完全可 ...

  5. WinForm 进程、线程、TreeView递归加载、发送邮件--2016年12月13日

    进程:一个程序就是一个进程,但是也有一个程序需要多个进程来支持的情况 进程要使用的类是:Process它在命名空间:System.Diagnostics; 静态方法Start(); Process.S ...

  6. 2016年3月13日 FXStreet首席分析师:欧元/美元下周走势展望

    FX168讯 欧元/美元在经历周初沉闷的走势之后,最终在欧洲央行出台一系列措施促进通货膨胀和经济增长之后怒涨至近一个月最高位.欧洲央行决议公布之前,投资者预期存款利率将下调10至15个基点,并可能进一 ...

  7. Android高级编程笔记(四)深入探讨Activity(转)

    在应用程序中至少包含一个用来处理应用程序的主UI功能的主界面屏幕.这个主界面一般由多个Fragment组成,并由一组次要Activity支持.要在屏幕之间切换,就必须要启动一个新的Activity.一 ...

  8. 我的Python成长之路---第八天---Python基础(24)---2016年3月5日(晴)

    多线程编程 什么是多线程,线程是操作系统能够进行运算调度的最小单位.他包含在进程之中,是进程中的实际运作单位.线程是进程中一个单顺序的空值六,一个进程可以并发多个线程,每个线程可以并行处理不同的任务. ...

  9. 我的Python成长之路---第七天---Python基础(22)---2016年2月27日(晴)

    socket网络编程 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. ...

随机推荐

  1. 第三章Struts2 Action中动态方法调用、通配符的使用

    01.Struts 2基本结构 使用Struts2框架实现用登录的功能,使用struts2标签和ognl表达式简化了试图的开发,并且利用struts2提供的特性对输入的数据进行验证,以及访问Servl ...

  2. CHM打不开的解决方法

    CHM打不开的解决方法 听语音 | 浏览:62240 | 更新:2013-02-04 14:58 | 标签:软件 1 2 3 4 5 6 分步阅读 一键约师傅 百度师傅高质屏和好师傅,拯救你的碎屏机 ...

  3. 87 resize2fs-增大或者收缩未加载的“ext2/ext3”文件系统的大小

    resize2fs命令被用来增大或者收缩未加载的"ext2/ext3"文件系统的大小.如果文件系统是处于mount状态下,那么它只能做到扩容,前提条件是内核支持在线resize., ...

  4. sys

    sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sys.maxi ...

  5. [转]struts2处理.do后缀的请求

    原文地址:http://skyuck.iteye.com/blog/545988 默认情况下,struts2是无法处理以.do为后缀的请求url的(默认情况下是.action或者不填,可以参见org. ...

  6. C#-WebForm-ASP开发练习:从数据库中动态添加信息

    传统的ASP开发方式,是C#代码和HTML代码混合在一起,ASP与ASP.NET不是一个东西. <%  %>  -  可以扩起来一段范围,这一段范围之内只能允许编写C#代码 <%= ...

  7. 使用IntelliJ IDEA 配置Maven(入门)

    1. 下载Maven 官方地址:http://maven.apache.org/download.cgi 解压并新建一个本地仓库文件夹 2.配置本地仓库路径   3.配置maven环境变量      ...

  8. DialogFragment is gone after returning back from another activity

    基本情景如下: 在DialogFragment中单击一个按钮跳转到another Activity做一些逻辑处理,然后将返回的结果回显到该DialogFragment上. 处理逻辑是: 在Dialog ...

  9. PHPstorm的数据库功能

    PHPstorm真是神器,居然有表.视图.存储过程的功能,非常人性化,建表那叫一个舒服,而且sql语句可以像其他代码一样显示"区域",结构更加清晰.

  10. Html中<a>标签的样式的设置

    html中<a>标签的样式的设置.. ------------------------ <html> <head> <title>这是网页选项卡的名称& ...