एरिक लिपर्ट ने इट्रेटर ब्लॉकों पर सीमाओं (और उन विकल्पों को प्रभावित करने वाले डिज़ाइन निर्णयों) पर लेखों की एक उत्कृष्ट श्रृंखला लिखी है
विशेष रूप से पुनरावृत्त ब्लॉकों को कुछ परिष्कृत संकलक कोड परिवर्तनों द्वारा कार्यान्वित किया जाता है। ये परिवर्तन उन परिवर्तनों के साथ प्रभावित होंगे जो गुमनाम कार्यों या लंबोदर के अंदर होते हैं जैसे कि कुछ परिस्थितियों में वे दोनों कोड को किसी अन्य निर्माण में बदलने की कोशिश करेंगे जो दूसरे के साथ असंगत था।
परिणामस्वरूप उन्हें बातचीत से मना किया जाता है।
कैसे हुड के नीचे iterator ब्लॉक काम अच्छी तरह से निपटाया जाता है यहाँ ।
एक असंगतता के सरल उदाहरण के रूप में:
public IList<T> GreaterThan<T>(T t)
{
IList<T> list = GetList<T>();
var items = () => {
foreach (var item in list)
if (fun.Invoke(item))
yield return item;
}
return items.ToList();
}
कंपाइलर एक साथ इसे कुछ इस तरह बदलना चाहता है:
private class Magic
{
private T t;
private IList<T> list;
private Magic(List<T> list, T t) { this.list = list; this.t = t;}
public IEnumerable<T> DoIt()
{
var items = () => {
foreach (var item in list)
if (fun.Invoke(item))
yield return item;
}
}
}
public IList<T> GreaterThan<T>(T t)
{
var magic = new Magic(GetList<T>(), t)
var items = magic.DoIt();
return items.ToList();
}
और एक ही समय में पुनरावृत्त पहलू यह करने की कोशिश कर रहा है कि यह एक छोटी सी मशीन बनाने के लिए काम करता है। कुछ सामान्य उदाहरण निष्पक्ष जांच (पहले मनमाने ढंग से) नेस्टेड क्लोजर () के साथ उचित मात्रा में काम करने के साथ काम कर सकते हैं, फिर यह देखते हुए कि क्या बहुत नीचे के स्तर के परिणामस्वरूप कक्षाएं पुनरावृत्त राज्य मशीनों में बदल सकती हैं।
हालाँकि यह होगा
- बहुत सारा काम।
- संभवतः सभी मामलों में काम नहीं कर सकते बिना बहुत कम से कम इटरेटर ब्लॉक के पहलू को दक्षता के लिए कुछ परिवर्तन लागू करने से रोकने में सक्षम होने के कारण (जैसे कि स्थानीय चर को पूरी तरह से बंद क्लोजर क्लास के बजाय स्थानीय चर को बढ़ावा देने के लिए)।
- यदि ओवरलैप की थोड़ी सी भी संभावना नहीं थी, जहां इसे लागू करना असंभव या पर्याप्त रूप से कठिन था, तो इसके परिणामस्वरूप समर्थन मुद्दों की संख्या अधिक होगी, क्योंकि कई उपयोगकर्ताओं पर सूक्ष्म ब्रेकिंग परिवर्तन खो जाएगा।
- इसके आसपास बहुत आसानी से काम किया जा सकता है।
आपके उदाहरण में ऐसा है:
public IList<T> Find<T>(Expression<Func<T, bool>> expression)
where T : class, new()
{
return FindInner(expression).ToList();
}
private IEnumerable<T> FindInner<T>(Expression<Func<T, bool>> expression)
where T : class, new()
{
IList<T> list = GetList<T>();
var fun = expression.Compile();
foreach (var item in list)
if (fun.Invoke(item))
yield return item;
}
async
अनुमति दे सकते हैंawait
, तो मैं यह जानना चाहूंगा कि वे अभी भी गुमनाम पुनरावृत्तियों कोyield
अंदर से लागू क्यों नहीं कर रहे हैं । कम या ज्यादा, यह एक ही राज्य मशीन जनरेटर है।