数组-->集合-->泛型
(1)数组
1. 数组数据结构是System.Array类的一个实例.
2. System.Array类的语法为
[SerializableAttribute]
[ComVisibleAttribute(true)]
public abstract class Array : ICloneable, IList, ICollection, IEnumerable
3. 下面看一个使用数组的例子(我称之为隐式实现)
protected void Page_Load( object sender, EventArgs e)
{
string [] strArrName = new string [ 3 ] { " Jim " , " Andy " , " Sun " };
foreach ( string strName in strArrName)
{
lblName.Text += strName + " , " ;
}
}
或者这样写
显示结果
protected void Page_Load( object sender, EventArgs e)
{
string [] strArrName = new string [ 3 ];
strArrName[ 0 ] = " Jim " ;
strArrName[ 1 ] = " Andy " ;
strArrName[ 2 ] = " Sun " ;
foreach ( string strName in strArrName)
{
lblName.Text += strName + " , " ;
}
}
如下
Jim,Andy,Sun,
4. 下面看另一个使用数组的例子(我称之为显式实现)
protected void Page_Load( object sender, EventArgs e)
{
Array myArray = Array.CreateInstance( typeof ( string ), 3 );
myArray.SetValue( " Jim " , 0 );
myArray.SetValue( " Andy " , 1 );
myArray.SetValue( " Sun " , 2 );
foreach ( string strName in myArray)
{
lblName.Text += strName + " , " ;
}
}
显示结果如下
Jim,Andy,Sun,
5. 优点:可以高效的访问给定下标的元素;System.Array类有自己的C#语法,使用它编程非常的直观.
6. 缺点:在实例化时必须指定数组的大小,以后也不能添加,插入,删除元素.
(2)集合
1. 针对数组数据结构的缺点,我们使用集合数据结构.
2. 集合数据结构中的类都位于System.Collections命名空间中.
3. 说到集合,我们必须先了解几个接口.想具体了解以下接口,可参考(3)集合接口
3.1 IEnumerable接口和IEnumerator接口
3.2 ICollection接口
public interface ICollection : IEnumerable
3.3 IList接口
public interface IList : ICollection, IEnumerable
3.4 IDictionary接口
public interface IDictionary : ICollection, IEnumerable
4. 说明一下:
4.1 ICollection接口是System.Collections命名空间中类的基接口.
4.2 ICollection接口扩展IEnumerable;IDictionary和IList则是扩展ICollection的更为专用的接口.IDictionary实现是键/值对的集合,如Hashtable类.IList实现是值的集合,其成员可通过索引访问,如ArrayList类.
4.3 某些集合(如Queue类和Stack类)限制对其元素的访问,它们直接实现ICollection接口.
4.4 如果IDictionary接口和IList接口都不能满足所需集合的要求,则从ICollection接口派生新集合类以提高灵活性.
(3)IEnumerable接口和IEnumerator接口
1. 我的理解:只有实现了IEnumerable接口的数据结构类才能使用foreach语句,下面给出例子
// Person类
public class Person
{
private string _firstName;
private string _lastName;
public string FirstName
{
get { return _firstName; }
}
public string LastName
{
get { return _lastName; }
}
public Person( string strFirstName, string strLastName)
{
this ._firstName = strFirstName;
this ._lastName = strLastName;
}
}
// PersonList集合,实现IEnumerable接口
public class PersonList : IEnumerable
{
private Person[] _arrPerson;
public PersonList(Person[] myArrPerson)
{
_arrPerson = new Person[myArrPerson.Length];
for ( int i = 0 ; i < myArrPerson.Length; i ++ )
{
_arrPerson[i] = myArrPerson[i];
}
}
public IEnumerator GetEnumerator()
{
return new PeopleEnumerator(_arrPerson);
}
}
// 实现IEnumerator接口
public class PeopleEnumerator : IEnumerator
{
private int _position = - 1 ;
public Person[] _arrPerson;
public object Current
{
get
{
try
{
return _arrPerson[_position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
public PeopleEnumerator(Person[] myArrPerson)
{
_arrPerson = myArrPerson;
}
public bool MoveNext()
{
_position ++ ;
return (_position < _arrPerson.Length);
}
public void Reset()
{
_position = - 1 ;
}
}
// 集合的使用
protected void Page_Load( object sender, EventArgs e)
{
Person[] myArrPerson = new Person[ 3 ]
{
new Person( " John " , " Smith " ),
new Person( " Jim " , " Johnson " ),
new Person( " Sue " , " Rabon " ),
};
PersonList myPersonList = new PersonList(myArrPerson);
foreach (Person myPerson in myPersonList)
{
lblName.Text += myPerson.FirstName + " " + myPerson.LastName + " , " ;
}
}
6. 说明一下我的理解,定义了一个集合类,实现IEnumerable接口,则必须定义一个与之相应的实现IEnumerator接口的类,这样是不是很麻烦呢?
(4)迭代器
1. 使用迭代器可避免上述麻烦,修改代码,注意橙色部分
public class Person
{
private string _firstName;
private string _lastName;
public string FirstName
{
get { return _firstName; }
}
public string LastName
{
get { return _lastName; }
}
public Person( string strFirstName, string strLastName)
{
this ._firstName = strFirstName;
this ._lastName = strLastName;
}
}
public class PersonList : IEnumerable
{
private Person[] _arrPerson;
public PersonList(Person[] myArrPerson)
{
_arrPerson = new Person[myArrPerson.Length];
for ( int i = 0 ; i < myArrPerson.Length; i ++ )
{
_arrPerson[i] = myArrPerson[i];
}
}
public IEnumerator GetEnumerator()
{
// 当编译器检测到迭代器时,它将自动生成IEnumerable或IEnumerable<T>接口的Current,MoveNext和Dispose方法.
for ( int i = 0 ; i < _arrPerson.Length; i ++ )
{
yield return _arrPerson[i];
}
}
}
例子
实现IEnumerable接口的类可以进行简单迭代,例如foreach语句
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace IEnumerable接口
{
class Program
{
static void Main( string [] args)
{
A a = new A();
foreach ( int ? var in a) // 当int值可能被赋空值时用?
{
Console.WriteLine(var);
}
}
}
class A : IEnumerable
{
int x = 1 ;
int y = 2 ;
int z = 3 ;
public IEnumerator GetEnumerator()
{
// int i = -1;
for ( int i = 0 ; i <= 3 ; i ++ )
{
if (i == x)
{
yield return 1 ;
}
else if (i == y)
{
yield return 2 ;
}
else if (i == z)
{
yield return 3 ;
}
else
{
yield return null ;
}
}
}
}
}