用人类自然的语言说泛型,保证一听既懂,一懂就会啦

转载 2008年09月29日 23:35:00
 泛型 
一、什么是泛型? 
通过泛型可以定义类型安全类,而不会损害类型安全、性能或工作效率 

二、实例化泛型 
1、可以使用任何类型来声明和实例化 
2、申明和实例话都必须用一个特定的类型来代替一般类型T 
3、例子: 
//原来写法 
Public   class   Stack 

object[]   m_Items; 
public   void   Push(object   item) 
{...} 
public   object   Pop() 
{...} 

Stack   stack   =   new   Stack(); 
stack.Push(1); 
int   number   =   (int)stack.Pop(); 

//有了泛型后 
Public   class   Stack <T> 

T[]   m_Items; 
public   void   Push(T   item) 
{...} 
public   T   Pop() 
{...} 

Stack <int>   stack   =   new   Stack <int> (); 
stack.Push(1); 
int   number   =   (int)stack.Pop(); 

三:泛型的好处 
1、一次性的开发、测试和部署代码,通过任何类型来重用它 
2、编译器支持和类型安全 
3、不会强行对值类型进行装箱和取消装箱,或者对引用类型进行向下强制类型转换,所以性能得到显著提高。 
注:值类型大概可以提高200%,引用类型大概为100% 

四:多个泛型 
1、单个类型可以定义多个泛型 

五:泛型别名 
1、在文件头部使用using   为特定类型取别名,别名作用范围是整个文件 
2、例子 
using   List   =   LinkedList <int,string> ; 
class   ListClient 

static   void   Main(string[]   args) 

List   list   =   new   List(); 
list.AddHead(123, "AAA "); 



五:泛型约束 
(1)、派生约束 
如: 
public   class   LinkedList <K,T>   where   K:IComparable 

T   Find(K   key) 

if   (str.Key.CompareTo(key)   ==   0)//只有实现这个接口才可比较 



注意: 
1、所有的派生约束必须放在类的实际派生列表之后 
如:public   class   LinkedList <K,T> :IEnumerable <T>   where   K:IComparable <K> 
        {...} 
2、一个泛型参数上可以约束多个接口(用逗号分隔) 
public   class   LinkedList <K,T>   where   K:IComparable <K> ,IConvertible 
3、在一个约束中最多只能使用一个基类 
4、约束的基类不能是密封类或静态类 
5、不能将System.Delegate或System.Array约束为基类 
6、可以同时约束一个基类以及一个或多个接口,但是该基类必须首先出现在派生约束列表中。 
7、C#允许你将另一个泛型参数指定为约束 
public   class   MyClass <T,U>   where   T:U 
{...} 
8、可以自己定义基类或接口进行泛型约束 
9、自定义的接口或基类必须与泛型具有一致的可见性 

(2)、构造函数约束 
如: 
class   Node   <K,T>   where   T:new() 


注意: 
1、可以将构造函数的约束和派生约束结合起来,前提是构造函数的约束出现在约束列表中的最后 

(3)、引用/值类型约束 
1、可以使用struct约束将泛型参数约束为值类型(如int、bool、enum),或任何自定义结构 
2、同样可以使用class约束将泛型参数约束为引用类型 
3、不能将引用/值类型约束与基类约束一起使用,因为基类约束涉及到类 
4、不能使用结构和默认构造函数约束,因为默认构造函数约束也涉及到类 
5、虽然您可以使用类和默认构造函数约束,但是这样做没有任何价值 
6、可以将引用/值类型约束与接口约束组合起来,前提是引用/值类型约束出现在约束列表的开头 

六:泛型和强制类型转换 
1、C#编译器只允许将泛型参数隐式转换到Object或约束指定的类型 
如: 
interface   IS{...} 
class   BaseClass{...} 
class   MyClass <T>   where   T:BaseClass,IS 

void   SomeMethod(T   t) 

IS   obj1   =   t; 
BaseClass   obj2   =   t; 
object   obj3   =   t; 


2、编译器允许你将泛型参数显示强制转换到其他任何借口,但不能将其转换到类 
interface   IS{...} 
class   SomeClass{...} 
class   MyClass   <T>   //没有约束 

void   SomeMethod(T   t) 

IS   obj1   =   (IS)t;   //可以 
SomeClass   obj2   =   (SomeClass)t   //不可以 


3、可以使用临时的Object变量,将泛型参数强制转换到其他任何类型 
class   SomeClass{...} 
class   MyClass   <T>   

void   SomeMethod(T   t) 

object   temp   =   t; 
SomeClass   obj   =   (SomeClass)temp;//可以 


注意:这里只是告诉你这样写是可以的,但是要不要这样写?不要这样写,因为如果t确实没有继承SomeClass编译没错但是运行就会出错 
4、解决上面强制转换问题,可以使用is和as运算符进行判断 
public   class   MyClass <T> 

public   void   SomeMethod <T   t> 

if   (t   is   int   ){...} 
if   (t   is   LinkedList <int,string> ){...} 
//如果泛型参数的类型是所查询的类型,则is运算符返回true 
string   str   =   t   as   string; 
//如果这写类型兼容,则as将执行强制类型转换,否则将返回null 
if   (str   !=   null){...} 
LinkedList <int,string>   list   =   t   as   LinkedList <int,string> ;
if   (list   !=   null){...} 



七:继承和泛型 
1、在从泛型基类派生,可以提供类型实参,而不是基类泛型参数 
public   class   BaseClass <T> {...} 
public   class   SubClass:BaseClass <int> 
2、如果子类是泛型,而非具体的类型实参,则可以使用子类泛型参数作为泛型基类的指定类型 
public   class   BaseClass <TT> {...} 
public   class   SubClass <T> :BaseClass <T> {...} 
3、在使用子类泛型参数时,必须在子类级别重复在基类级别规定的任何约束 
4、基类可以定义其签名使用泛型参数的虚礼方法,在重写它们时,子类必须在方法签名中提供相应的类型。 
如: 
public   class   BaseClass <T> 

public   virtual   T   SomeMethod() 
{...} 

public   class   SubClass:BaseClass <int> 

public   override   int   SomeMethod() 
{...} 

5、如果该子类是泛型,则它还可以在重写时使用它自己的泛型参数 
public   class   SubClass <T> :BaseClass <T> 

public   override   T   SomeMethod() 
{...} 

6、你可以定义泛型接口、泛型抽象类,甚至泛型抽象方法。 
7、不能对泛型参数使用+或+=之类的运算符 
public   class   Calculator <T> 

public   T   Add   (T   arg1,T   arg2) 

return   arg1   +   arg2;//错误 


但是我们可以通过泛型抽象类、接口来实现在个功能,因为实现泛型抽象类、接口我们就已经明确传一个参数了,就可以执行诸如+这样的操作。 

八:泛型方法 
1、方法可以定义特定于其执行范围的泛型参数 
public   class   MyClass <T> 

public   void   MyMethod <X> (X   x) 
{...} 

2、即使各包含类根本不使用泛型,你也可以定义方法特定的泛型参数 
public   class   MyClass 

public   void   MyMethod <T> (T   t) 
{...} 

注意:该功能只使用于方法,属性,索引器只能使用在类的作用范围中定义的泛型参数。 
3、调用泛型方法 
MyClass   obj   =   new   MyClass(); 
obj.MyMethod <int> (3); 
也可以这样: 
MyClass   obj   =   new   MyClass(); 
obj.MyMethod(3);   //该功能称为泛型推理 
4、泛型方法也可以有自己的泛型参数约束 
pubic   class   MyClass 

public   void   SomeMethod <T> (T   t)   where   T:IComparable <T> 
{...} 

5、子类方法实现不能重复在父级别出现的约束 
public   class   BaseClass 

public   virtual   void   SomeMethod <T> (T   t)where   T:new() 
{...} 

pubic   class   SubClass:BaseClass 

public   override   void   SomeMethod <T> (T   t)//不能再有约束 
{...} 

6、静态方法 
静态方法可以定义特定的泛型参数和约束 
public   class   MyClass <T> 

public   static   T   SomeMethod <X> (T   t,X   x) 
{...} 

int   number   =   MyClass <int> .SomeMethod <string> (3, "AAA "); 
或者:int   mumber   =   MyClass <int> .SomeMethod(3, "AAA "); 

九:泛型委托 
1、在某个类中定义的委托可以利用该类的泛型参数 
2、委托也可以定义自己的泛型参数

做一个有温度,懂情趣,会生活的人

这是我第一篇博客文章,第一次想分享自己的生活而不是技术问题。        跟大家说说我昨天的经历吧,失业的第二天也就是昨天,去找朋友玩,朋友的朋友是个算命师,他说我倒霉,去哪家公司哪家公司倒闭,他说...
  • YvonneZhangYL
  • YvonneZhangYL
  • 2015年10月16日 12:51
  • 673

你真的懂Java泛型吗

泛型实现参数化类型的概念,使代码可以应用于多种类型,解除类或方法与所使用的类型之间的约束。在JDK 1.5开始引入了泛型,但Java实现泛型的方式与C++或C#差异很大。在平常写代码用到泛型时,仿佛一...
  • TellH
  • TellH
  • 2017年05月07日 11:40
  • 3059

美国VPN你懂的!!

一直都想在手机上用youtube,但是一直没有找到合适的代理软件和好的免费vpn,今天偶尔发现了一个超赞的免费vpn提供商,虽然没有goagent那么牛x但是也是很牛叉了!不限时不限速!!注册后在自己...
  • u014609236
  • u014609236
  • 2014年05月18日 21:17
  • 370

C 语言中模拟“泛型”

一般在写 C 程序时用 typedef 将容器中元素的类型抽象,无法在同一个程序中用到两种类型,而本文试图在一个程序中用到两种不同类型的容器,比如实现类似于 C++ 中的 vector 和 vecto...
  • Justme0
  • Justme0
  • 2014年02月07日 22:44
  • 2880

为什么每个程序员都应该懂点前端知识?

本文作者为 OneAPM 工程师李哲,文章主要介绍前端知识对于编程的必要性。
  • wangpeng198688
  • wangpeng198688
  • 2016年06月28日 10:55
  • 686

程序员必须了解的内存知识

C和C++语言开发中,指针、内存一直是学习的重点。因为C语言作为一种偏底层的中低级语言,提供了大量的内存直接操作的方法,这一方面使程序的灵活度最大化,同时也为bug埋下很多隐患。 因此,无论如何...
  • haozi0_0
  • haozi0_0
  • 2015年12月13日 14:10
  • 734

听故事搞懂多线程开发-- 屎壳郎老板和它的收费公厕

刚接触开发的童鞋,在学习多线程的时候,往往会比较吃力.因为这家伙比较抽象,有的时候较难通过运行代码直接看到多线程操作应该有的实际效果.和UI相比,多线程部分更注重理解. 所以,希望能通过这个...
  • qq_16379603
  • qq_16379603
  • 2015年08月21日 18:07
  • 205

你真正理解什么是“财富自由吗”?

对于我们“凡人”来说,实现个人财富自由并非遥不可及!
  • u011465086
  • u011465086
  • 2017年06月11日 12:41
  • 176

不要告诉我你懂margin

转自 海玉的博客 原文地址: http://www.hicss.net/do-not-tell-me-you-understand-margin/ 你真的了解margin吗?你知道margi...
  • ljl157011
  • ljl157011
  • 2013年11月19日 20:14
  • 1013

区块链究竟是什么鬼?看完漫画秒懂!

区块链究竟是什么鬼?看完漫画秒懂! 区块链技术是指一种全民参与记账的方式。所有的系统背后都有一个数据库,你可以把数据库看成是就是一个大账本。目前是...
  • u010786200
  • u010786200
  • 2017年11月20日 10:00
  • 226
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用人类自然的语言说泛型,保证一听既懂,一懂就会啦
举报原因:
原因补充:

(最多只允许输入30个字)