2014-10-31 12 views
7

मैं 101 LINQ Samples in the MSDN page का उपयोग कर LINQ सीख रहा हूँ और मैं इस कोड में आए:लेकडाइंड पैरामीटर कैसे लेते हैं?

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 

var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index); 

foreach (var n in firstSmallNumbers) 
{ 
    Console.WriteLine(n); 
} 

इस समारोह का उद्देश्य जब तक एक संख्या है कि मारा जाता है सरणी के प्रारंभ से लेकर तत्वों लौटने के लिए "TakeWhile उपयोग करने के लिए है सरणी में इसकी स्थिति से कम है। "

वास्तव में n और index पता है कि कौन सा पैरामीटर लेना है? (यानी n कैसे पता चलता है कि यह 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 ले जाएगा और index कैसे जानता है कि यह 0, 1, 2, 3 ... की वृद्धि करेगा?)?

+1

मैंने आपका शीर्षक बदल दिया। यदि इसका मतलब यह नहीं है कि आपका क्या मतलब है, तो कृपया इसे बदलें। – gunr2171

+0

मैं आपके परिवर्तनों से सहमत हूं, धन्यवाद। –

उत्तर

9

क्योंकि ओवरलोड को इस तरह परिभाषित किया गया है।से MSDN

public static IEnumerable<TSource> TakeWhile<TSource>(
    this IEnumerable<TSource> source, 
    Func<TSource, int, bool> predicate 
) 

predicate तर्क इस प्रकार वर्णित है:

एक शर्त के लिए प्रत्येक स्रोत तत्व का परीक्षण करने के लिए एक समारोह; फ़ंक्शन का दूसरा पैरामीटर स्रोत तत्व की अनुक्रमणिका का प्रतिनिधित्व करता है।

TSource तर्क आइटम है, और int सूचकांक है। bool वापसी मूल्य है।

जब आप (n, index) => ... लिखने n पहले पैरामीटर (TSource) लेता है और index दूसरा (int) लेता है।

+1

तो आप कह रहे हैं कि इससे कोई फर्क नहीं पड़ता कि मैं पैरामीटर का नाम कैसे देता हूं? (यानी मैं इसे '(कुछElse1, somethingElse2) => 'का नाम बदल सकता हूं और यह अभी भी काम करेगा? –

+3

@ सीजे सही है। आप एक अज्ञात विधि को परिभाषित कर रहे हैं, पैरामीटर नाम आपके ऊपर हैं। – BradleyDotNET

+3

@CJ इसे आजमाएं और ढूंढें बाहर। आपके पास पहले से ही कोड है। – Servy

3

पहला पैरामीटर n संख्याओं की संख्या से जुड़ा हुआ है और दूसरा index अनुक्रम में संख्या के सूचकांक से जुड़ा हुआ है। असल में, इससे कोई फर्क नहीं पड़ता कि आप उन्हें n और index नाम दें, आप जो भी नाम दे सकते हैं। किसी भी मामले में पहला पैरामीटर अनुक्रम में यादृच्छिक आइटम और इस अनुक्रम की अनुक्रमणिका के साथ दूसरा पैरामीटर से जुड़ा होगा।

public static IEnumerable<TSource> TakeWhile<TSource>(
    this IEnumerable<TSource> source, 
    Func<TSource, int, bool> predicate 
) 

हम से TakeWhile ऊपर एक विस्तार विधि प्रकार पर परिभाषित कि IEnumerable इंटरफ़ेस लागू करता है देखने के रूप में:

के रूप में और अधिक औपचारिक रूप ब्राडली TakeWhile की परिभाषा ऊपर कहा गया है निम्नलिखित है। अब दो चीजें ध्यान दें, पैरामीटर जो इस विधि को इनपुट करते हैं और इसका रिटर्न प्रकार होता है।

यह आपूर्ति अनुक्रम में मौजूद वस्तुओं के प्रकार की वस्तुओं का अनुक्रम देता है।

पैरामीटर के रूप में क्या लेता है?

एक अनुमान। एक अनुमान एक विधि है जो कुछ पैरामीटर लेती है और true या false देता है। भविष्यवाणी के पैरामीटर क्या हैं?

भविष्यवाणी के पैरामीटर TSource तत्व हैं, और int हैं। TSource तत्व आपके अनुक्रम का यादृच्छिक तत्व होगा int इस तत्व का सूचकांक होगा।

यह (n, index) => n >= index अब क्या है?

यह एक लैम्ब्डा अभिव्यक्ति है, जो एक भविष्यवाणी की तरह कार्य करता है।

Specifficaly, चर n और index कहा जाता है, को देखते हुए रिटर्न truen>=index अगर अन्यथा false. रिटर्न TakeWhile विस्तार विधि को यह अभिव्यक्ति की आपूर्ति वहाँ एक Func<TSource, int, bool> विधेय गुजर की तरह है। तो आप जो चाहते हैं उसे प्राप्त करें।

+0

कृपया डाउनवॉटर मुझे बताएं कि मैं कहां गलत हूं। पहले ही, आपका बहुत धन्यवाद। – Christos

+0

डाउनवॉटर नहीं, लेकिन यह आपके उत्तर के बहुत पहले संशोधन पर आया था। मुझे लगता है कि उन्होंने इस (बहुत बेहतर) संस्करण को नहीं देखा है। – BradleyDotNET

+0

@BradleyDotNET आपकी टिप्पणी के लिए बहुत बहुत धन्यवाद। – Christos

4

लैम्ब्डा अभिव्यक्ति में, => से पहले सबकुछ विधि के पैरामीटर हैं। उदाहरण के लिए, (n, index) => n >= index लैम्ब्डा अभिव्यक्ति के लिए एक विधि इस के समान के रूप में लिखा जा सकता है:

public bool CheckIfValueIsGreaterOrEqualToIndex(int value, int index) 
{ 
    if(value >= index) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

ताकि पद्धति का उपयोग करके, आप जो भी नाम आप मापदंडों करना चाहते हैं (इस उदाहरण में मैं value इस्तेमाल किया बजाय निर्दिष्ट कर सकते हैं n)। ,

public static List<int> MyTakeWhile(this List<int> input, Func<int, int, bool> predicate) 
{ 
    var result = new List<int>(); 
    for (var i = 0; i < input.Count; i++) 
    { 
     if (predicate(input[i], i)) 
      result.Add(input[i]); 
     else 
      break; 
    }; 
    return result; 
} 

आप वास्तविक जीवन में एक yield return का प्रयोग करेंगे:

numbers.TakeWhile(CheckIfValueIsGreaterOrEqualToIndex); 
2

सबसे अच्छा तरीका कोशिश करते हैं और अपने खुद के सरलीकृत TakeWhile विधि लागू करने के लिए किया जाएगा: और लैम्ब्डा के बजाय आपको लगता है कि विधि यहाँ इस्तेमाल कर सकते हैं और एक IEnumerable वापस करें और, ज़ाहिर है, int के बजाय जेनेरिक का उपयोग करें। लेकिन विचार वही है।

आप इसे परीक्षण करना चाहते हैं:

var numbers = new List<int> { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 
var result = numbers.MyTakeWhile((n, index) => n >= index); 
result.ForEach(Console.WriteLine); 

यह {5, 4} जो बिल्कुल मूल TakeWhile रूप में ही है देना चाहिए।

+0

भले ही यह सीखने का एक उचित तरीका है; यह वास्तव में ओपी को सीखने में मदद नहीं करता है कि लैम्ब्डा अभिव्यक्ति कैसे काम करती है। – BradleyDotNET

संबंधित मुद्दे