yield
כמו שהבטחתי
בפוסט הקודם אני אראה דרך קצרה יותר לממש את IEnumerable ללא מימוש עצמאי של IEnumerator בעזרת yield.
ראשית נראה את הדוגמא ואז את ההסברים:
הנה המחלקה מהפוסט הקודם:
class PersonManager : IEnumerable
{
private List<Person> _persons;
public PersonManager()
{
_persons = new List<Person>();
}
public IEnumerator GetEnumerator()
{
}
}
כעת נממש את המתודה בעזרת yield.
public IEnumerator GetEnumerator()
{
foreach (var item in _persons)
{
yield return item;
}
}
למעשה אפשר פשוט להשתמש בזה, במידה וחשוב לכם לדעת מה קורה מאחורי הקלעים אתם מוזמנים לפתוח
relector ותראו שנוצרת מחלקה שלמה, כשהמתודה העיקרית נראית כך:
private bool MoveNext()
{
try
{
switch (this.state)
{
case 0:
this.state = -1;
this.wrap = this.@this._persons.GetEnumerator();
this.state = 1;
while (this.wrap.MoveNext())
{
this.item = this.wrap.Current;
this.current = this.item;
this.state = 2;
return true;
Label_0072:
this.state = 1;
}
this.m__Finally3();
break;
case 2:
goto Label_0072;
}
return false;
}
finally
{
((IDisposable)this).Dispose();
}
}
,
כשבפעם הראשונה שהמתודה תקרא הערך של state יהיה 0.
(לא ברור לי כיצד אפשר ב - case 2 לקרוא ל - Label_0072 כשהוא מוגדר בסקופ של ה - while - אולי למייקרוסופט מותר לעשות דברים שלנו אסור ?)