IEnumerator
迭代器是一个可以逐个访问集合中元素的方法或属性。在C#中,实现迭代器的常见方法是通过实现IEnumerable和IEnumerator接口。然而,这种方法可能会涉及大量的样板代码来维护状态和位置。
using System;
using System.Collections;
namespace dotnetLearn.迭代器学习
{
public class IEnumerableShow
{
public static void testShow()
{
Student student = new Student { Id = 1 };
foreach (var item in student)
{
Console.WriteLine(item);
}
}
}
class Student : IEnumerable
{
public int Id { get; set; }
public IEnumerator GetEnumerator()
{
string[] student = { "Ant编程1", "Ant编程2", "Ant编程3" };
return new StudentEnumerator(student);
}
}
internal class StudentEnumerator : IEnumerator
{
string[] _student;
int _position = -1;
public StudentEnumerator(string[] student)
{
this._student = student;
}
public object Current
{
get
{
if (_position == -1)
{
throw new InvalidOperationException();
}
if (_position >= _student.Length)
{
throw new InvalidOperationException();
}
return _student[_position];
}
}
public bool MoveNext()
{
if (_position < _student.Length - 1)
{
_position++;
return true;
}
else
{
return false;
}
}
public void Reset()
{
_position = -1;
}
}
}
yield
为了简化编写迭代器的过程,C#引入了yield关键字。yield允许你在方法或属性中编写代码,使其能够逐个返回集合中的元素,而不需要显式地实现IEnumerable和IEnumerator接口。
使用yield return可以逐个返回元素,而使用yield break可以提前终止迭代
下面就是相比上面相同的实现,但是代码简洁很多。
using System;
using System.Collections;
using System.Collections.Generic;
namespace dotnetLearn.迭代器学习
{
public class YieldTest
{
public static void testShow()
{
Student student = new Student { Id = 1 };
foreach (var item in student)
{
Console.WriteLine(item);
}
}
}
class Student2 : IEnumerable
{
public int Id { get; set; }
public IEnumerator GetEnumerator()
{
//返回一个枚举器
yield return "Ant编程1";
yield return "Ant编程2";
yield return "Ant编程3";
}
}
}
DEMO
public class YieldTest : MonoBehaviour
{
void Start()
{
var it = FuncWithYield();
it.MoveNext();
Debug.Log(it.Current);
it.MoveNext();
Debug.Log(it.Current);
it.MoveNext();
Debug.Log(it.Current);
}
public static IEnumerator<string> FuncWithYield()
{
string res = "";
res = "这是第一句话";
yield return res;
res = "这是第二句话";
yield return res;
res = "这是第三句话";
yield return res;
res = "这是第四句话";
yield return res;
}
}
类似js中generator函数
function* getName() {
console.log('函数开始执行');
const value1 = 'tom'
console.log(value1)
yield value1
const value2 = 'mary'
console.log(value2);
yield value2
console.log('函数执行结束')
}
// 返回生成器
const iterator = getName()
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
// 函数开始执行
// tom
// { value: 'tom', done: false }
// { value: 'mary', done: false }
// { value: 'tony', done: false }
// '函数执行结束'
// { value: undefined, done: true }