.NET 泛型的问题

呵呵 其实我这个ID 和allenzhang0004 allenzhang0003都是一个人。
关键是我有太多问题要弄明白了,所以逼不得已 注册这么多号。

正题:今天看泛型 基本都懂了 

看完肯定会有疑问的,我的疑问就是 项目里什么时候用泛型???

看 了一篇BLOg 说是只要是集合类型在.NET2.0以后都可以用泛型去代替。。。

求证。当然是实际项目里泛型的使用!

 

搞技术还是得一步一个脚印,不懂就问,也别怕别人笑你菜。

别人也是从菜变成高手的。

很鄙视嘴里说简单 简单 但做不出来东西的 人。。。

不过人家也混的好,呵呵 每个人观点不一样

 

泛型是一种强大的编程机制,可以这么理解,我们生活中有一种螺丝刀是可以更换头的,更换不同的螺丝头就可以旋开不同的螺钉,可以把螺丝刀的旋开螺钉的这个 操作,理解为是支持泛型的一个例子。

又比如,对数组元素进行排序,通过应用泛型技术,就可以编写出通用的排序方法,不管数组元素是什么类 型,都可以应用该方法进行排序。

 

你可以看看金旭亮老师编写的《.NET 2.0面向对象编程揭秘(附光盘)》

那部书说的很不错。

 

为避免集合类弊端,在Net2.0中引入了泛型.泛型其实可以理解为一个强类型的集合类.在ADO.net中,也有类似的改进,那就是强类型 Dataset的引入
在运行时才能确定类型的集合运算时
提高性能,特别是在类型转换时

 

复用的时候如果只是值不同,那么就用函数来解决,把不同的值传入即可,
但是如果类型不同的时候怎么办,泛型最大的好处就是这里,可以“传入”类型

 

eg:
ArrayList 元素为object
List<T> 元素为T类型对象

当用的集合中什么 类型都有时,用ArrayList
当只有一种类型时,用List<T>

当元素为值类型时,ArrayList操作涉 及到装箱,拆箱; 而List<T> 不会,因为T已经说明了类型

 

根据偶的理解,泛型是程序员贪心的产物,
他们做了个数组,就希望里面什么都能装.于是有了List<>
他们写了个方法,就希 望这个方法不管什么样的数据类型都能处理,于是就有了 void mymethod<T>
他们写了个类,就希望这个类可以管很多种数 据类型,于是就有了 class myclass<T>

于是乎,当你看到<>出现的时候,你只要理解,眼前的这 个贪心的东东,他是想要处理很多种数据类型..
泛型往往又会和委托在一起,而委托恰好可理解为可以调用各种不同的方法(函数指针)
再于是 乎,他们俩臭气相投,一配合贪心无限大,可以调用很多方法来处理很多的类型...

 

2.0 版 C# 语言和公共语言运行库 (CLR) 中增加了泛型。估计现在绝大多数人都用过了,而且用得最多的就是泛型集合List<T>,以至于现在一说到泛型,很多人的第一反应就是 List<T>,在这里我要说说,把泛型等同于List<T>的乃是还没有真正理解泛型的人。为了让大家能够更好的理解泛型,故 开此贴,欢迎大家积极发表自己的意见(btw:如果你只会在这个帖子里回“学习”两字,但其实什么都没学到的话,那我还是奉劝你还是不要回了,还不如到别 的散分贴接点分来得实在)


首先来说说什么是泛型,泛型是.net framework2.0版本以后才出现的新东西,泛型的英文为Generic,意为“通用”,翻译成为泛型之后更能体现其优点:广泛的类型。设想有这么 一个情况,你正在设计一个自定义类型,这个类里面的很多方法都要传进一个参数,但这个参数的类型在设计阶段还不能知道它是什么类型的,那怎么办呢?在泛型 出来之前,我们只能用所有类型的object类型来进行定义,但是用object会有很多问题,比如你的参数传进来以后你要把它强制转换类型,这就涉及到 代码的隐患了,另外还有就是如果是值类型的话,还会有装箱和拆箱的各种性能损耗。为了解决这些问题,于是泛型出现了,在定义的时候,你只要将不确定的类定 义为泛型类型,在使用的时候,根据需要用特定的类型来代替泛型类型,这就保证了类型的安全性,并且减少了装拆箱的性能损耗。所以泛型最普遍的就是用来定义 泛型集合类。

以下为MSDN对泛型的概述:
泛型概述
使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。

泛 型最常见的用途是创建集合类。

.NET Framework 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。应尽可能地使用这些类来代替普通的类,如 System.Collections 命名空间中的 ArrayList。

您可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。

可以对泛型类进行约束以访问特 定数据类型的方法。

关于泛型数据类型中使用的类型的信息可在运行时通过使用反射获取。


一般情况下,创建泛型类的 过程为:从一个现有的具体类开始,逐一将每个类型更改为类型参数,直至达到通用化和可用性的最佳平衡。创建您自己的泛型类时,需要特别注意以下事项:

1、 将哪些类型通用化为类型参数。

通常,能够参数化的类型越多,代码就会变得越灵活,重用性就越好。但是,太多的通用化会使其他开发人员难以 阅读或理解代码。

2、如果存在约束,应对类型参数应用什么约束

一条有用的规则是,应用尽可能最多的约束,但仍使您能够处 理必须处理的类型。例如,如果您知道您的泛型类仅用于引用类型,则应用类约束。这可以防止您的类被意外地用于值类型,并允许您对 T 使用 as 运算符以及检查空值。

3、是否将泛型行为分解为基类和子类。

由于泛型类可以作为基类使用,此处适用的设计注意事项与非泛 型类相同。请参见本主题后面有关从泛型基类继承的规则。

4、是否实现一个或多个泛型接口。

例如,如果您设计一个类,该类 将用于创建基于泛型的集合中的项,则可能必须实现一个接口,如 IComparable<T>,其中 T 是您的类的类型。


C# 泛型和 C++ 模板都是用于提供参数化类型支持的语言功能。然而,这两者之间存在许多差异。在语法层面上,C# 泛型是实现参数化类型的更简单方法,不具有 C++ 模板的复杂性。此外,C# 并不尝试提供 C++ 模板所提供的所有功能。在实现层面,主要区别在于,C# 泛型类型替换是在运行时执行的,从而为实例化的对象保留了泛型类型信息。

以下是 C# 泛型和 C++ 模板之间的主要差异: 

C# 泛型未提供与 C++ 模板相同程度的灵活性。例如,尽管在 C# 泛型类中可以调用用户定义的运算符,但不能调用算术运算符。

C# 不允许非类型模板参数,如 template C<int i> {}。

C# 不支持显式专用化,即特定类型的模板的自定义实现。

C# 不支持部分专用化:类型参数子集的自定义实现。

C# 不允许将类型参数用作泛型类型的基类。

C# 不允许类型参数具有默认类型。

在 C# 中,尽管构造类型可用作泛型,但泛型类型参数自身不能是泛型。C++ 确实允许模板参数。

C++ 允许那些可能并非对模板中的所有类型参数都有效的代码,然后将检查该代码中是否有用作类型参数的特定类型。C# 要求相应地编写类中的代码,使之能够使用任何满足约束的类型。例如,可以在 C++ 中编写对类型参数的对象使用算术运算符 + 和 - 的函数,这会在使用不支持这些运算符的类型来实例化模板时产生错误。C# 不允许这样;唯一允许的语言构造是那些可从约束推导出来的构造。


------------------------------------------------------------------------
应 8楼的要求,列几个例子说明一下:
下面的代码示例演示一个用于演示用途的简单泛型链接列表类。(大多数情况下,应使用 .NET Framework 类库提供的 List<T> 类,而不是自行创建类。)在通常使用具体类型来指示列表中存储的项的类型的场合,可使用类型参数 T。其使用方法如下:

在 AddHead 方法中作为方法参数的类型。

在 Node 嵌套类中作为公共方法 GetNext 和 Data 属性的返回类型。

在 嵌套类中作为私有成员数据的类型。

注意,T 可用于 Node 嵌套类。如果使用具体类型实例化 GenericList<T>(例如,作为 GenericList<int>),则所有的 T 都将被替换为 int。

C# code
   

// 在三角符号里写入类型参数T
public class GenericList < T >
{
// Node为非泛型类,作为GenericList<T>的嵌套类
private class Node
{
// 在非泛型构造函数中使用T
public Node(T t)
{
next
= null ;
data
= t;
}

private Node next;
public Node Next
{
get { return next; }
set { next = value; }
}

// T作为私有成员的数据类型
private T data;

// T作为属性的返回类型
public T Data
{
get { return data; }
set { data = value; }
}
}

private Node head;

// 构造函数
public GenericList()
{
head
= null ;
}

// T 作为方法的参数类型
public void AddHead(T t)
{
Node n
= new Node(t);
n.Next
= head;
head
= n;
}

public IEnumerator < T > GetEnumerator()
{
Node current
= head;

while (current != null )
{
yield return current.Data;
current
= current.Next;
}
}
}




下面的代码示例演示客户端代码如何使用泛型 GenericList<T> 类来创建整数列表。只需更改类型参数,即可方便地修改下面的代码示例,创建字符串或任何其他自定义类型的列表:

C# code
   

class TestGenericList
{
static void Main()
{
// int 是类型变量
GenericList < int > list = new GenericList < int > ();

for ( int x = 0 ; x < 10 ; x ++ )
{
list.AddHead(x);
}

foreach ( int i in list)
{
System.Console.Write(i
+ " " );
}
System.Console.WriteLine(
" /n完成 " );
}
}


 

来源:nba视频直播

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值