2008-08-19 11 views
12

मुझे पता है कि yield क्या करता है, और मैंने कुछ उदाहरण देखे हैं, लेकिन मैं वास्तविक जीवन अनुप्रयोगों के बारे में नहीं सोच सकता, क्या आपने इसे कुछ विशिष्ट समस्या हल करने के लिए उपयोग किया है?उपज के वास्तविक जीवन अनुप्रयोग क्या हैं?

(आदर्श रूप में कुछ समस्या यह है कि किसी अन्य तरीके से हल नहीं किया जा सकता है)

उत्तर

8

मुझे एहसास है कि यह एक पुराना प्रश्न है (पूर्व जॉन स्कीट?) लेकिन मैं हाल ही में इस सवाल पर विचार कर रहा हूं। दुर्भाग्य से यहां वर्तमान उत्तरों (मेरी राय में) उपज कथन का सबसे स्पष्ट लाभ का उल्लेख नहीं करते हैं।

उपज कथन का सबसे बड़ा लाभ यह है कि यह आपको मानक सूची कहने के बाद बहुत अधिक कुशल स्मृति उपयोग के साथ बहुत बड़ी सूचियों पर फिर से शुरू करने की अनुमति देता है।

उदाहरण के लिए, मान लीजिए कि आपके पास डेटाबेस क्वेरी है जो 1 मिलियन पंक्तियां लौटाती है। आप DataReader का उपयोग करके सभी पंक्तियां पुनर्प्राप्त कर सकते हैं और उन्हें एक सूची में स्टोर कर सकते हैं, इसलिए स्मृति की list_size * row_size बाइट्स की आवश्यकता होती है।

या आप एक इटरेटर बनाने के लिए उपज कथन का उपयोग कर सकते हैं और एक समय में स्मृति में केवल एक पंक्ति को स्टोर कर सकते हैं। असल में यह आपको डेटा के बड़े सेटों पर "स्ट्रीमिंग" क्षमता प्रदान करने की क्षमता देता है।

इसके अलावा, इटरेटर का उपयोग करने वाले कोड में, आप एक साधारण फोरैच लूप का उपयोग करते हैं और आवश्यकतानुसार लूप से बाहर निकलने का निर्णय ले सकते हैं।यदि आप जल्दी तोड़ते हैं, तो आपने डेटा के पूरे सेट को पुनर्प्राप्त करने के लिए मजबूर नहीं किया है जब आपको केवल पहली पंक्तियों (उदाहरण के लिए) की आवश्यकता होती है।

के बारे में

:

Ideally some problem that cannot be solved some other way 

उपज बयान आप कुछ भी आप अपने स्वयं के कस्टम इटरेटर कार्यान्वयन का उपयोग नहीं कर सका नहीं देता है, लेकिन यह आप अक्सर जटिल कोड की जरूरत लिखने के लिए की आवश्यकता होगी, बचत होती है। बहुत कम समस्याएं हैं (यदि कोई है) जो एक से अधिक तरीकों से हल नहीं हो सकती हैं।

Yield keyword value added?

Is yield useful outside of LINQ?

5

वास्तव में मैं अपनी साइट IdeaPipe

public override IEnumerator<T> GetEnumerator() 
{ 
    // goes through the collection and only returns the ones that are visible for the current user 
    // this is done at this level instead of the display level so that ideas do not bleed through 
    // on services 
    foreach (T idea in InternalCollection) 
     if (idea.IsViewingAuthorized) 
      yield return idea; 
} 
तो मूल रूप से यह जाँच करता है, तो विचार को देखने वर्तमान में है

पर एक गैर परंपरागत तरीके से इसका इस्तेमाल अधिकृत और यदि यह विचार है तो यह विचार देता है। यदि यह नहीं है, तो यह सिर्फ छोड़ दिया गया है। यह मुझे विचारों को कैश करने की अनुमति देता है लेकिन अभी भी उन उपयोगकर्ताओं को विचार प्रदर्शित करता है जो अधिकृत हैं। अन्यथा मुझे अनुमतियों के आधार पर उन्हें हर बार खींचना होगा, जब वे केवल 1 घंटे फिर से रैंक किए जाते हैं।

1

एन्यूमेरेबल क्लास पर LINQ के ऑपरेटरों को उपज कथन के साथ बनाए गए इटरेटर के रूप में लागू किया जाता है। जब तक आप वास्तव में एक लूप में गणक का उपयोग नहीं करते हैं, तो आम तौर पर फोरैच कथन का उपयोग करके चयन() और कहां() को चुनने के लिए चुनिंदा() और कहां() जैसे श्रृंखला संचालन की अनुमति देता है। साथ ही, जब आप IEnumerator.MoveNext() को कॉल करते हैं तो केवल एक मान गणना की जाती है यदि आप मध्य-संग्रह को रोकने का निर्णय लेते हैं, तो आप सभी परिणामों की गणना करने के प्रदर्शन हिट को सहेज लेंगे।

इटरेटर्स का उपयोग अन्य प्रकार के आलसी मूल्यांकन को लागू करने के लिए भी किया जा सकता है जहां अभिव्यक्ति का मूल्यांकन केवल तभी किया जाता है जब आपको इसकी आवश्यकता होती है। आप coroutines जैसे अधिक फैंसी सामान के लिए उपज का भी उपयोग कर सकते हैं।

1

उपज के लिए एक और अच्छा उपयोग उदाहरण के लिए, एक IEnumerable के तत्वों पर एक समारोह में प्रदर्शन करने के लिए और एक अलग प्रकार का एक परिणाम के वापस जाने के लिए है:

public delegate T SomeDelegate(K obj); 

public IEnumerable<T> DoActionOnList(IEnumerable<K> list, SomeDelegate action) 
{ 
    foreach (var i in list) 
     yield return action(i); 
} 
2

एक दिलचस्प उपयोग अतुल्यकालिक प्रोग्रामिंग के लिए एक तंत्र के रूप में है उन कार्यों के लिए esp जो कई चरणों को लेते हैं और प्रत्येक चरण में डेटा के समान सेट की आवश्यकता होती है। इसके दो उदाहरण जेफ़री रिचर्स ऐसनेक्यूमेरेटर Part 1 और Part 2 होंगे। Concurrency और समन्वय रनटाइम (सीसीआर) भी इस तकनीक का उपयोग CCR Iterators का उपयोग करता है।

1

उपज का उपयोग एक ठोस प्रकार के लिए डाउनकास्टिंग को रोक सकता है। यह सुनिश्चित करने के लिए आसान है कि संग्रह का उपभोक्ता इसका उपयोग नहीं करता है।

0

तुम भी yield return का उपयोग एक सूची के रूप में कार्य परिणामों की एक श्रृंखला के इलाज के लिए कर सकते हैं:

यहाँ कि अधिक विवरण प्रदान अधिक हाल ही में सवाल और जवाब के एक जोड़े हैं। उदाहरण के लिए, एक ऐसी कंपनी पर विचार करें जो हर दो सप्ताह में अपने कर्मचारियों को भुगतान करे। कोई भी इस कोड का उपयोग कर सूची के रूप में पेरोल तिथियों का सबसेट पुनर्प्राप्त कर सकता है:

void Main() 
{ 
    var StartDate = DateTime.Parse("01/01/2013"); 
    var EndDate = DateTime.Parse("06/30/2013"); 
    foreach (var d in GetPayrollDates(StartDate, EndDate)) { 
     Console.WriteLine(d); 
    } 
} 

// Calculate payroll dates in the given range. 
// Assumes the first date given is a payroll date. 
IEnumerable<DateTime> GetPayrollDates(DateTime startDate, DateTime endDate, int  daysInPeriod = 14) { 
    var thisDate = startDate; 
    while (thisDate < endDate) { 
     yield return thisDate; 
     thisDate = thisDate.AddDays(daysInPeriod); 
    } 
} 
संबंधित मुद्दे