निम्नलिखित LINQ स्टेटमेंट कैसे काम करता है?


160

निम्नलिखित LINQ स्टेटमेंट कैसे काम करता है ?

यहाँ मेरा कोड है:

var list = new List<int>{1,2,4,5,6};
var even = list.Where(m => m%2 == 0);
list.Add(8);
foreach (var i in even)
{
    Console.WriteLine(i);
}

आउटपुट: 2, 4, 6, 8

क्यों नहीं 2, 4, 6?


102
क्वेरी अभिव्यक्ति का परिणाम एक क्वेरी है, क्वेरी का निष्पादन नहीं।
एरिक लिपर्ट

6
कम जानकारी के लिए इस प्रश्न का स्वीकृत उत्तर देखें ।
डैनियल

9
निश्चित रूप से आप एक शीर्षक के बारे में सोच सकते हैं जो वास्तव में प्रश्न को संक्षेप में प्रस्तुत करता है।
मैट बॉल

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

जवाबों:


235

उत्पादन होता है 2,4,6,8की वजह से स्थगित कर निष्पादन

क्वेरी वेरिएबल को वास्तव में निष्पादित किया जाता है, जब क्वेरी वैरिएबल से अधिक पुनरावृति होती है, न कि जब क्वेरी वैरिएबल बनाया जाता है। इसे आस्थगित निष्पादन कहा जाता है।

- सुप्रोटिम अग्रवाल, " लाइनक्यू में स्थगित बनाम तत्काल क्वेरी"

एक और निष्पादन है जिसे तत्काल क्वेरी निष्पादन कहा जाता है , जो क्वेरी परिणामों को कैशिंग करने के लिए उपयोगी है। सुप्रोटीम अग्रवाल से फिर:

एक क्वेरी के तत्काल निष्पादन के लिए मजबूर करने के लिए जो एक सिंगलटन मान का उत्पादन नहीं करता है, आप क्वेरी या क्वेरी चर पर ToList(), ToDictionary(), ToArray(), Count(), Average()या Max()विधि को कॉल कर सकते हैं । इन्हें रूपांतरण ऑपरेटर कहा जाता है जो आपको परिणाम की एक कॉपी / स्नैपशॉट बनाने की अनुमति देते हैं और क्वेरी को फिर से निष्पादित करने की आवश्यकता के बिना, जितनी बार चाहें उतनी बार पहुंच सकते हैं।

यदि आप चाहते हैं कि आउटपुट हो 2,4,6, तो उपयोग करें .ToList():

var list = new List<int>{1,2,4,5,6};
var even = list.Where(m => m%2 == 0).ToList();
list.Add(8);
foreach (var i in even)
 {
    Console.WriteLine(i);
 }

8
गणना (), मैक्स (), औसत (), सम () और शायद अन्य विधियां जिन्हें पूरी सूची को ध्यान में रखने की आवश्यकता है, क्वेरी के मूल्यांकन का कारण भी हैं।
केनेड जूल

1
मैंने अक्सर एक फ़िल्टर के रूप में 'फ़िल्टरडलिस्ट' को एक चर के रूप में कहने के बारे में सोचा है, एक विधि के रूप में - विचार होने के नाते, आप हर बार जब आप सूची को फ़िल्टर्ड करना चाहते हैं, तो एक विधि को कॉल करने के बजाय उस पर पुनरावृति करें। एक दिलचस्प हो सकता है, अगर असामान्य और शायद अपूर्ण प्रदर्शन-वार, चीजों को करने का तरीका।
कटाना ३१४

4
@Sebastian - @ kenned की टिप्पणी करने के लिए इसके अलावा, .First(), .FirstOrDefault(), .Single()और .SingleOrDefault()भी क्वेरी के मूल्यांकन ट्रिगर।
स्कूटी.नेट

4
आश्चर्यजनक रूप से आपको 30 सेकंड से कम समय में जवाब कैसे मिला: D
MC

2
@ मुझे नहीं पता कि आप यह सवाल क्यों पूछ रहे हैं। एक बार में पूरा जवाब नहीं दिया गया। इसे कई बार संपादित किया गया था।
आतिश दीपोंगकोर - एमवीपी

11

यह आस्थगित निष्पादन के कारण हुआ है, जिसका अर्थ है कि अभिव्यक्ति की गणना को तब तक निष्पादित नहीं किया जाता है जब तक कि उसे किसी जगह की आवश्यकता न हो। यदि डेटा बहुत बड़ा है तो यह प्रदर्शन को बेहतर बनाता है।


3
आप इसकी बारीकियों को समझ सकते हैं, क्योंकि इसका मतलब यह भी हो सकता है कि आपके महँगी गणना को कई बार निष्पादित किया जा रहा है। ऐसे मामले में आपको प्रदर्शन हानि भी हो सकती है।
डेसपायर की

0

इसका कारण आपके लैम्ब्डा अभिव्यक्ति का आस्थगित निष्पादन है। जब आप फ़ॉरेस्ट लूप में चलना शुरू करते हैं, तो क्वेरी निष्पादित हो जाती है।


11
तकनीकी तौर पर इसके बारे में आस्थगित निष्पादन है इटरेटर , नहीं लैम्ब्डा
डी स्टेनली

0

जब आप LINQ से प्राप्त एक IEnumerable <> का उपयोग करते हैं, तो केवल एक एन्यूमरेटर वर्ग बनाया जाता है और पुनरावृत्ति केवल तब शुरू होती है जब आप इसे कुछ चलने में उपयोग करते हैं।


-1

आप इस परिणाम को आस्थगित निष्पादन के कारण प्राप्त कर रहे हैं जिसका अर्थ है कि परिणाम का मूल्यांकन तब तक नहीं किया जाता है जब तक कि यह पहली बार पहुंच न जाए।

इसे और अधिक स्पष्ट करने के लिए बस अपने स्निपेट के अंत में सूची में 10 जोड़ें और फिर प्रिंट करें आपको आउटपुट में 10 नहीं मिलेगा

     var list = new List<int>{1,2,4,5,6};
    var even = list.Where(m => m%2 == 0).Tolist();
    list.Add(8);
    foreach (var i in even)
    {
        Console.WriteLine(i);
    }
//new*
    list.Add(10);
    foreach (var i in even)
    {
        Console.WriteLine(i);
    }

क्या आपने वास्तव में कोशिश की थी? मैं 10आउटपुट में मिलता हूं ।
मार्क जॉर्डन

अच्छा पकड़ @MarkHurd ने जोड़ा नहीं है .ToList () पोस्ट को संपादित किया अब उसे अपेक्षित आउटपुट देना चाहिए। मेरी उम्मीद की अभिव्यक्ति का मूल्यांकन केवल तब किया गया जब आप पहली बार var का उपयोग करते हैं, लेकिन ऐसा लगता है कि इसका मूल्यांकन हर बार हो रहा है
sandeep

अब इसमें 8या तो आउटपुट नहीं होगा ।
मार्क जर्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.