要想使用foreach遍历就要使这个类继承自IEnumerabler接口,foreach的底部也是调用的这个接口里面的函数
只有实现了IEnumerable接口的类(也叫做可枚举类型)才能进行foreach的遍历操作,集合和数组已经实现了这个接口,所以能进行foreach的遍历操作
集合继承IEnumerable这个接口,而IEnumerable的 IEnumerator GetEnumerator()方法 可以获得一个可用于循环访问集合的 对象
没有
不知道怎么才能解释清楚,自己实现一个foreach就知道怎么回事了
// Person类包括两个属性。
public class Person
{
public Person(string fName, string lName)
{
this.firstName = fName;
this.lastName = lName;
}
public string firstName;
public string lastName;
}
//People类就是Person的集合,里边使用了一个数组把单个的对象存在这个数组当中。而且因为实现了
//IEnumerable接口,所以要实现GetEnumerator方法,返回一个实现了IEnumerator的类。
public class People : IEnumerable
{
private Person[] _persons;
//重新开辟内存来存储
public People(Person[] _p)
{
_persons = new Person[_p.Length];
for(int i = 0; i < _p.Length; i++)
{
_persons[i] = _p[i];
}
}
public IEnumerator GetEnumerator()
{
return new PeopleEnum(_persons);
}
}
// 这里我们需要定义一套逻辑去遍历上边的集合。
public class PeopleEnum : IEnumerator,IDisposable
{
private Person[] _persons;
// Enumerators are positioned before the first element
// until the first MoveNext() call.
int position = -1;
public PeopleEnum(Person[] list)
{
_persons = list;
}
bool IEnumerator.MoveNext()
{
position++;
return (position < _persons.Length);
}
void IEnumerator.Reset()
{
position = -1;
}
void IDisposable.Dispose()
{
Console.WriteLine("释放资源。。。");
}
object IEnumerator.Current
{
get
{
try
{
return _persons[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
}
class App
{
static void Main()
{
Person[] peopleArray = new Person[3]
{
new Person("John", "Smith"),
new Person("Jim", "Johnson"),
new Person("Sue", "Rabon"),
};
People peopleList = new People(peopleArray);
//在这里使用foreach就可以遍历这个集合了,因为它实现了IEnumerable接口。
foreach (Person p in peopleList)
Console.WriteLine(p.firstName + " " + p.lastName);
//其实foreach的底层就是干了以下的事情
IEnumerator enumerator = peopleList.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
Person element; //post C# 5
element = (Person)enumerator.Current;
//下边这句就是原来foreach方法体中的逻辑
Console.WriteLine(element.firstName + " " + element.lastName);
}
}
finally
{
//如果这个类继承了IDisposable接口,就可以用来释放资源
IDisposable disposable = enumerator as System.IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
}
}