搜索
简帛阁>技术文章>黑马程序员_学习日记7_C#基础归纳总结之泛型

黑马程序员_学习日记7_C#基础归纳总结之泛型

---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ----------------------

 

什么是泛型?

  泛型是.NET 2.0引入的一个概念。泛型不仅是C#语言的一部分,而且与程序集中的IL代码紧密继承。有了泛型 我们就可以创建于独立于被包含类的类和方法了。

泛型不仅是C#的语言结构,而且还是由CLR定义的。那么既然是CLR定义的,那么只要是支持CLR的语言就都支持泛型,于是我们很快就能联想到VB.NET。

 

为什么要有泛型?

   首先第一点:性能

   在.NET中数据类型分为值类型和引用类型。从值类型到引用类型的转换 我们称之为装箱,从引用类型到值类型的转换 我们称之为装箱。

装箱和拆箱会消耗很多资源。特变是在遍历一个集合的时候。

一般的值类型对象和引用类型对象之间的转换工作会涉及到装箱和拆箱,这种过程对系统开销是比较大的。 泛型类不需要装箱拆箱的操作。因为(这里是书上的原话):泛型类不使用对象,而是在使用时定义类型,比如List的泛型类型定义为int,int类型就会在JIT及时编译的类中使用,所以它不在进行装箱和拆箱的操作。 
  个人对这段话的理解:泛型类型 和一般类型不一样,一般类型之间的转换是由.Net提供的默认的装箱和拆箱的操作,这个工程是普遍的。优点是 可以对不同数据类型的数据都执行这种操作,缺点是开销大,效率低。
  而泛型 是会根据 你定义了泛型类型,此类型会在JIT中及时编译成一个动态类,它不需要数据转化,无需装箱拆箱的操作,所以就没有必要调用.NET提供的默认的装箱拆箱的运算。 优点是 效率提高了,缺点是没有普遍使用性。因为 泛型数据类型已经确定了。

 第二点:安全性

   泛型中定义了允许使用的类型,是使用泛型处理该数据时,如果数据类型不对,编译器就会给出错误提示。

比如说 var list = new list();

list.Add("我");//编译器不会让你通过,

foreach( int i in list)

{

   //遍历不涉及装箱拆箱的操作提高系统效率

}

 

第三点:代码重用

     泛型可以更好的重用二进制代码.泛型类型可以定义一次,就可以用于许多不同类型的数据类型的实例化。
例子:var list = new list(); list.Add(1);var list = new list();list.Add(2);
  var list = new list();list.Add(new student());
我对这个例子是这么理解的:因为所有的代码会通过编译器编程成微软中间语言IL CLR又会将微软中间语言编译成平台能识别的机器码,机器码是不是1100100这样的二进制 我不知道,但是代码最终就编译成1010010这样的代码 。
上述的例子中 new list这块是不变的,变的是T.也就是说 由List提供的一些基本方法:比如Add 它从始至终都是不会变的。于是我们可以把它直接就转换成二进制代码 来提高系统运行效率。免得每次 你定义一个新的T类型 都要把List重新通过N多环节编译成1010010 费时费力。 

泛型约束:

 where T:Struct    泛型类型T必须是值类型

 where T:class     泛型类型T必须是引用类型

 where T:IFoo      泛型T必须实现IFoo接口

 where T:Foo       泛型T必须继承是类Foo

 where T:new()     指定的类型T必须包含一个不带参数的构造函数

 where T1;T2        泛型类型T1派生自泛型类型T2 此类型约束也称之为“裸约束”

 

下面我们就为where T:IFoo 泛型类型必须实现某个接口 来敲一个例子。

创建一个DocumentManager类 用来管理文档信息,不过不是传统的DocumentManager而是泛型的DocumentManager

public class DocumentManager<TDocument> where TDocument:IDocument

{

       private readonly Queue<T> documentQue = new Queue<T>();//文档数据队列
//将T数据类型文档添加到当前队列
public void AddDocument<T>(T doc)
{
     lock(this)
     {
         documentQue.Enqueue(doc);
     }
}

//返回当前队列是否有文档。
public bool IsDocumentAvailable
{
   get{return documentQue.Length>0;}
}

public T GetDocument()
{
     //defalut关键字 给值类型赋0,引用类型赋null
     T doc = default(T);
     lock(this)
     {
         doc = documentQue.Dequeue();
     }
return doc;
}
 //显示所有的文档通过上述约束可以将T转化为IDocument类型      
public void DisplayAllDoucment()
{
     foreach(T doc in documentQue)
     {
           IDocument Id = doc;
           Console.WriteLine(Id.Title);
           Console.WriteLine(Id.Content);
     }
}
}
//现在在对应一个IDocument的接口 来确定Document数据类型必须包含的信息
public interface IDocument
{
   string Title{get;set;}
   string Content{get;set;}
}

//定义一个Document的类来实现IDocument接口
public class Document:IDocument
{
   //属性自动实现(不清楚见学习笔记1)
   public string Title{get;set;}
   public string Content{get;set;}


    public Document(string title,string content)
{
  this.Title = title;
   this.Content= content;
}
}
     

然后 我们在前台:
var dm = new DocumentManager<Document>();//Document实现了IDocument 才能作为DocumentManager的泛型类型
dm.AddDocument(new Document("Asp.Net自定义控件开发","野战鹰"));
dm.AddDocuemt(new Document("C#高级编程第七版","Wrox"));
dm.DisplayAllDocument();
//我们在此方法中 又将每一个传入进去的Document对象转化为了IDocument接口类型。
 
if(dm.IsDocumentAvailable)
{<!-- -->
   IDocument Id = dm.GetDocument();
   Console.WriteLine(Id.Content);
}
 
 


泛型继承:

 

 泛型类型可以继承实现泛型接口,也可以派生自泛型类.
当泛型类型派生自泛型类时:它必须满足下面两个条件之一:
其一:必须重复基类的泛型类型;
其二:在基类中为其指定泛型数据类型;

例子:
基类泛型 Base ,派生类泛型Derived;
必须是: Derived:Base 或者是 Derived:Base

于是派生类可以使泛型也可以是非泛型(条件二:Base已经为派生类指定了需要处理的数据类型)


泛型静态成员:泛型静态成员只能在类的一个实例中共享。

eg:

 public class StaticDemo

{

   public static int x;

}

 

StaticDemo.x=5;

StaticDemo.x=6;

Console.WriteLine(StaticDemo.x);//6

 

泛型接口

一般老的接口比如

Interface IComparable

{

   //参数类型一般都为object 原因是微软不知道具体要实现的这个类类中对该方法的实现

//要传递一个什么样类型的参数。

    int CompareTo(object obj);

}

所以每次实现起来 都会有一个装箱的操作。

public class Person:IComparable

{

    public int CompareTo(object obj)

  {

       Person other = obj as Person;//装箱

      if(condition)

     {

          //内部逻辑

    }

  }

}

 

但是 如果我们顶一个泛型接口的话,就可以省掉这么一个装箱的操作了。

Interface IComparable

{

   int CompareTo(T t);

 

}

 

public class Person:IComparable

{

    public int compareTo(Person p)

     {

         if(conditon)

          {

               //...逻辑......

         }

  }

}

 

 

泛型方法:

 也可以把方法定义成泛型的

 void Swap(ref T t1,ref T t2)

{

    Console.WriteLine*(t1+t2).ToString());

}

 

调用时可以

Swap(ref 1,ref 2);

也可以

Swap(ref 1,ref 2);

编译器会根据参数类型来推断T的类型。

---------------------- Windows Phone 7手机开发、 .Net培训、期待与您交流! ----------------------
详细请查看: http://net.itheima.com/
WindowsPhone7手机开发、Net培训、期待与您交流!什么是?泛型是NET20引入的一个概念。泛型不仅是C语言的一部分,而且与程序集中的IL代码紧密继承。有了我们就可以创建于独立于被
indowsPhone7手机开发、Net培训、期待与您交流!CSDN终于可以发帖了,把前几天的补上4月12日今晚网速很慢,下黑马视频很卡,我下了一本《C基础教程》的电子书来学习,做笔记如下:一、IL
android培训、java培训、期待与您交流!的基本应用泛型是java15中的一个新特性。没有使用泛型时,只要是对象,不管是什么类型的对象,都可以存储进同一个集合中。使用集合,可以讲一个集合
android培训、java培训、期待与您交流!反射的基础Class类反射并不是java15中的特性,而是java12版本中就具备这个特性。先来了解反射所需的基础Class类。Java程序中的各个Ja
android培训java培训期待与您交流!下午学习了高新技术部分的内容,感觉知识点又多又细,可能是之前没有接触过这些东西,在看视频的时候理解起来有点吃力,所以就把所学的东西大概地整理了一下,顺便复习
C基本知识点一、C与NET的关系NET的核心是CLR(公共语言运行时)。在CLR中运行的代码,我们称为“托管代码”。我们写的代码在运行之前,会经过两个编译阶段:1、把源代码编译为IL(Microso
ndroid培训、java培训、期待与您交流!2011年8月6日星期六接着学习的知识,但一开始刚听到这个词,对它根本没什么感念,心里想着这是什么东东,结下来的视频学习会不会异常的艰难呢不自
android培训、java培训、期待与您交流!静态导入importstatic静态导入(importstatic)是java15中的新特性之一,为了书写的简便,可以通过静态导入的方式导入某一个类中的
——android培训、java培训、期待与您交流!———概述:JDK15版本以后出现新特性。用于解决安全问题,是一个类型安全机制。好处1将运行时期出现问题ClassCastException
——android培训、java培训、期待与您交流!———2的基本使用练习:比较字符串长度,按字符串长度排序!分析:字符串本身是具备比较性的intcompareTo(Stringstr);但是这里