C# IEnumerable 和 IEnumerator
IEnumerable 和 IEnumerator区别
这段时间写点基础文章,这次写的是C# IEnumerable
和 IEnumerator
,这两者的区别在于:
IEnumerable
其意义就是表示可以被枚举的
,其中会调用到GetEnumerator()
。IEnumerator
表示的是一个枚举器
,其实现的是Current
,MoveNext
,Reset
。
简单的例子
因为Array
中本身就实现了GetEnumerator
,所以我们可以这么写:
public class BookInfo {
public string name {get;set;}
public int price { get; set; }
public BookInfo(string name, int price) {
this.name = name;
this.price = price;
}
}
public class BookIEnumerable : IEnumerable
{
private BookInfo[] Books;
public BookIEnumerable(BookInfo[] books)
{
Books = (BookInfo[])books.Clone();
}
public BookIEnumerable(List<BookInfo> books)
{
Books = books.ToArray();
}
public IEnumerator GetEnumerator()
{
return Books.GetEnumerator();
}
}
// 我们可以在下面看见我们直接对new出来的对象进行了foreach遍历
BookInfo[] books = {
new BookInfo("蛇皮1",1),
new BookInfo("蛇皮2",2),
new BookInfo("蛇皮3",3),
new BookInfo("蛇皮4",4),
new BookInfo("蛇皮5",5)
};
BookIEnumerable booksIEnumerable = new BookIEnumerable(books);
foreach (BookInfo book in booksIEnumerable)
{
Console.Write("{0} {1}\n", book.name, book.price);
}
自己实现 IEnumerator
public class BookIEnumerable : IEnumerable
{
private List<BookInfo> Books;
public BookIEnumerable(BookInfo[] books)
{
Books = books.ToList();
}
public BookIEnumerable(List<BookInfo> books)
{
Books = books;
}
public IEnumerator GetEnumerator()
{
//自己实现 IEnumberator
return new BooksIEnumerator(Books);
}
}
public class BooksIEnumerator : IEnumerator
{
private int index = -1;
private List<BookInfo> Books;
public BooksIEnumerator(IEnumerable<BookInfo> books) {
Books = books.ToList();
}
public object Current {
get {
if (index < 0 || index > Books.Count)
return null;
else
return Books[index];
}
}
public bool MoveNext()
{
index++;
if (index < Books.Count && Books[index] != null)
return true;
return false;
}
public void Reset()
{
index = -1;
}
}
IEnumerable还可以是方法的返回类型
我们使用yield
关键字就可以自己做一个Iterator
的东西。
public class Books
{
private List<BookInfo> Books;
public Books(BookInfo[] books)
{
Books = books.ToList();
}
public Books(List<BookInfo> books)
{
Books = books;
}
public IEnumerable<BookInfo> getIterator() {
if (Books.Count > 0)
{
foreach (var b in Books) {
yield return b;
}
}
else {
yield return null;
}
}
}
使用起来也很方便
Books books = new Books(bookList);
var iterator = books.getIterator();
foreach (BookInfo book in iterator)
{
Console.Write("{0} {1}\n", book.name, book.price);
}
实用性
举个栗子来说明IEnumerable的实用性
//书本实体类
public class BookInfo {
public string name {get;set;}
public int price { get; set; }
public BookInfo(string name, int price) {
this.name = name;
this.price = price;
}
}
//shopping类
public class Shopping
{
private ValueCalculator vc;
public Shopping(ValueCalculator vc)
{
this.vc = vc;
}
public IEnumerable<BookInfo> AllBooks { get; set; }
public decimal CalculateBookTotal()
{
return vc.ValueBooks(AllBooks);
}
}
//计算器
public class ValueCalculator
{
public decimal ValueBooks(IEnumerable<BookInfo> books)
{
//IEnumerable中的sum方法
return books.Sum(b => b.price);
}
}