在数组和集合中,我们介绍了一个简单实用的可变长数组ArrayList。这个类可以动态的扩充和收缩集合的长度,用起来非常的方便。但ArrayList有一个不好的地方,就是该类是弱类型,什么乱七八糟的数据类型都可以通通放入一个ArrayList的实例中。
为了解决这个问题,我们使用继承来建立一个自己的强类型类。
那么,对于这个继承方案有什么不足的地方吗?
有人说,为了实现一个强类型类,要写这么多代码,不爽,吐血。虽然这是事实,但我们好歹也是程序员,拜托不要说出这么没有素质的话。
我们仔细观察我们的StringArrayList代码中的自定义方法。我们发现,这些方法其实都是包装了CollectionBase的受保护的属性List。这个List是实现IList接口。
IList接口对Add的定义为
int Add (Object value)
你是不是感觉到了问题了?为达到我们的自定义强类型的集合,编译器一直再做两件事情:
当我们做的是值类型集合时,比如:intColl、boolColl、charColl时,编译器不停的在执行装箱行为,把我们定义的Add传入的值类型,包装了object。
当我们做的是引用类型集合是,比如:stringColl时,编译器不停的在作数据类型转换,将实际的数据类型转为最高的object。
可以想象一下,这样的强类型集合是多么的消耗资源和CPU时间。
为了解决这个问题,我们使用继承来建立一个自己的强类型类。
那么,对于这个继承方案有什么不足的地方吗?
有人说,为了实现一个强类型类,要写这么多代码,不爽,吐血。虽然这是事实,但我们好歹也是程序员,拜托不要说出这么没有素质的话。
我们仔细观察我们的StringArrayList代码中的自定义方法。我们发现,这些方法其实都是包装了CollectionBase的受保护的属性List。这个List是实现IList接口。
IList接口对Add的定义为
int Add (Object value)
你是不是感觉到了问题了?为达到我们的自定义强类型的集合,编译器一直再做两件事情:
当我们做的是值类型集合时,比如:intColl、boolColl、charColl时,编译器不停的在执行装箱行为,把我们定义的Add传入的值类型,包装了object。
当我们做的是引用类型集合是,比如:stringColl时,编译器不停的在作数据类型转换,将实际的数据类型转为最高的object。
可以想象一下,这样的强类型集合是多么的消耗资源和CPU时间。
现在你知道了,浪费你写代码时间是小事,消耗了系统的资源时间才是大罪过。阿弥陀佛。
那有没有比较好的办法来解决呢?.NET Framework 2.0给出了泛型解决方案。为此,.NET Framework新加了一个命名空间:System.Collections.Generic,该命名空间包含定义泛型集合的接口和类,泛型集合允许用户创建强类型集合,它能提供比非泛型强类型集合更好的类型安全性和性能。
该命名空间下有一个List类,这个类是AyyarList的泛型等效类。
看看下面的代码
看看下面的代码
1
System.Collections.Generic.List
<
Int32
>
intList
=
new
List
<
int
>
();
2
intList.Add(
1
);
3
intList.Add(
2
);
4
intList.Add(
3
);
5
int
sum
=
0
;
6
for
(
int
i
=
0
; i
<=
intList.Count
-
1
; i
++
)
7
{
8
sum += intList[i];
9
}
10
11
System.Console.WriteLine(sum);
12
13
System.Collections.Generic.List
<
string
>
stringList
=
new
List
<
string
>
();
14
stringList.Add(
"
Hello
"
);
15
stringList.Add(
"
C#
"
);
16
stringList.Add(
"
Generic
"
);
17
string
s
=
string
.Empty; ;
18
for
(
int
i
=
0
; i
<=
stringList.Count
-
1
; i
++
)
19
{
20
s += stringList[i] + " ";
21
}
22
System.Console.WriteLine(s);
23
24
System.Collections.Generic.List
<
DateTime
>
dataList
=
new
List
<
DateTime
>
();
25
dataList.Add(DateTime.Now);
26
System.Console.WriteLine(dataList[
0
].AddDays(
15
));
System.Collections.Generic.List
<
Int32
>
intList
=
new
List
<
int
>
();2
intList.Add(
1
);3
intList.Add(
2
);4
intList.Add(
3
);5
int
sum
=
0
;6
for
(
int
i
=
0
; i
<=
intList.Count
-
1
; i
++
)7
{8
sum += intList[i];9
}
10

11
System.Console.WriteLine(sum);12

13
System.Collections.Generic.List
<
string
>
stringList
=
new
List
<
string
>
();14
stringList.Add(
"
Hello
"
);15
stringList.Add(
"
C#
"
);16
stringList.Add(
"
Generic
"
);17
string
s
=
string
.Empty; ;18
for
(
int
i
=
0
; i
<=
stringList.Count
-
1
; i
++
)19
{20
s += stringList[i] + " ";21
}
22
System.Console.WriteLine(s);23
24
System.Collections.Generic.List
<
DateTime
>
dataList
=
new
List
<
DateTime
>
();25
dataList.Add(DateTime.Now);26
System.Console.WriteLine(dataList[
0
].AddDays(
15
));
使用了System.Collections.Generic.List类,在声明是描述<Int32>或<string>或<DateTime>,就告诉了编译器,该类所允许的数据类型。多Cool啊。
仔细观察
sum += intList[i];
s += stringList[i] + " ";
dataList[0].AddDays(15)
这三条语句,告诉我们,实用了泛型集合,当取出数据值的时候,编译器是不需要重新作卸箱和数据类型转换的。换句话将,在装入值的时候,编译器也没有作装箱和数据转换。仅对于这个点List要比AyyarList要快的多(特别是在处理值类型的时候)。
仔细观察
sum += intList[i];
s += stringList[i] + " ";
dataList[0].AddDays(15)
这三条语句,告诉我们,实用了泛型集合,当取出数据值的时候,编译器是不需要重新作卸箱和数据类型转换的。换句话将,在装入值的时候,编译器也没有作装箱和数据转换。仅对于这个点List要比AyyarList要快的多(特别是在处理值类型的时候)。
那么是不是说,我们上次写的stringArrayList就没有用了?直接用List就可以了?哈哈,对了。吐血了吧。
因为泛型带类了强类型处理,所以泛型类最常用于集合,如链接列表、哈希表、堆栈、队列、树等,其中,像从集合中添加和移除项这样的操作都以大体上相同的方式执行,与所存储数据的类型无关。
所以我推荐,在新的应用.NET Framework 2.0平台是,请大家忘记原先的弱类型集合,尽量的实用泛型所带来了强类型集合。
原先的ArrayList现在由List对应
原先的Hashtable现在由Dictionary 对应
原先的抽象类CollectionBase 现在由非抽象类Collection对应
原先的抽象类ReadOnlyCollectionBase 现在由非抽象的ReadOnlyCollection对应
原先的Queue、Stack 和 SortedList现在都有同名的泛型类来对应
所以我推荐,在新的应用.NET Framework 2.0平台是,请大家忘记原先的弱类型集合,尽量的实用泛型所带来了强类型集合。
原先的ArrayList现在由List对应
原先的Hashtable现在由Dictionary 对应
原先的抽象类CollectionBase 现在由非抽象类Collection对应
原先的抽象类ReadOnlyCollectionBase 现在由非抽象的ReadOnlyCollection对应
原先的Queue、Stack 和 SortedList现在都有同名的泛型类来对应
除了可以对应的类型外,.NET Framework 2.0提供了几个新的类来实现通用的数据类型
下面的代码演示了作为通用的双向链表类System.Collections.Generic.LinkedLis的用法。
1
string
[] letters
=
"
Visual Studio 是一套完整的工具,用于生成桌面和基于团队的企业级 Web 应用程序。
"
.Split(
new
char
[]
{ ' ', ',', '。' }
);
2
foreach
(
string
s
in
letters)
3
{
4
System.Console.WriteLine(s);
5
}
6
System.Collections.Generic.LinkedList
<
string
>
wordList
=
new
LinkedList
<
string
>
(letters);
7
//
通过双向链表可以直接的对元素定义,而不需要遍历循环
8
System.Console.WriteLine(
"
wordList有元素:{0},第一个是{1},最后一个是{2}
"
, wordList.Count, wordList.First.Value, wordList.Last.Value);
9
letters
=
"
简化基于团队的企业级解决方案的设计、开发和部署
"
.Split(
new
char
[]
{ ' ', ',', '。', '、' }
);
10
foreach
(
string
s
in
letters)
11
{//在最后节点插入
12
wordList.AddAfter(wordList.Last, s);
13
}
14
System.Console.WriteLine(
"
wordList有元素:{0},第一个是{1},最后一个是{2}
"
, wordList.Count, wordList.First.Value, wordList.Last.Value);
15
letters
=
"
除了生成高性能的桌面应用程序外,还可以使用 Visual Studio 基于组件的强大开发工具和其他技术,
"
.Split(
new
char
[]
{ ' ', ',', '。', '、' }
);
16
foreach
(
string
s
in
letters)
17
{//在最后节点插入
18
wordList.AddAfter(wordList.Find("应用程序"), s);
19
foreach (string tmps in wordList)
20
{
21
System.Console.Write("{0} ", tmps);
22
}
23
System.Console.WriteLine();
24
}
25
string
[] letters
=
"
Visual Studio 是一套完整的工具,用于生成桌面和基于团队的企业级 Web 应用程序。
"
.Split(
new
char
[]
{ ' ', ',', '。' }
);2
foreach
(
string
s
in
letters)3
{4
System.Console.WriteLine(s);5
}
6
System.Collections.Generic.LinkedList
<
string
>
wordList
=
new
LinkedList
<
string
>
(letters);7
//
通过双向链表可以直接的对元素定义,而不需要遍历循环
8
System.Console.WriteLine(
"
wordList有元素:{0},第一个是{1},最后一个是{2}
"
, wordList.Count, wordList.First.Value, wordList.Last.Value);9
letters
=
"
简化基于团队的企业级解决方案的设计、开发和部署
"
.Split(
new
char
[]
{ ' ', ',', '。', '、' }
);10
foreach
(
string
s
in
letters)11
{//在最后节点插入12
wordList.AddAfter(wordList.Last, s);13
}
14
System.Console.WriteLine(
"
wordList有元素:{0},第一个是{1},最后一个是{2}
"
, wordList.Count, wordList.First.Value, wordList.Last.Value);15
letters
=
"
除了生成高性能的桌面应用程序外,还可以使用 Visual Studio 基于组件的强大开发工具和其他技术,
"
.Split(
new
char
[]
{ ' ', ',', '。', '、' }
);16
foreach
(
string
s
in
letters)17
{//在最后节点插入18
wordList.AddAfter(wordList.Find("应用程序"), s);19
foreach (string tmps in wordList)20
{21
System.Console.Write("{0} ", tmps);22
}23
System.Console.WriteLine();24
}
25
本文转自shyleoking 51CTO博客,原文链接:http://blog.51cto.com/shyleoking/806261