2009-07-08 12 views
10

मैं एक MatchCollection वस्तु के खिलाफ एक LINQ क्वेरी चलाने के लिए चाहता था, लेकिन पाया के रूप में यह ICollection<T> को लागू नहीं करता है, सिर्फ ICollection यह संभव नहीं था लागू करने वर्गों के साथ LINQ का उपयोग करना।गैर सामान्य ICollection

कोड समेकन के संदर्भ में, गैर-जेनेरिक संग्रह के साथ LINQ का उपयोग करने के लिए सबसे अच्छा विकल्प क्या है, बल्कि प्रदर्शन और स्मृति उपयोग दोनों के मामले में?

(यदि रुचि रखते हैं, यहां गैर LINQuified कोड :) कास्ट एक्सटेंशन विधि है जो एक IEnumerable वापस आ जाएगी उपयोग करने के लिए

MatchCollection fieldValues = Regex.Matches(fieldValue, @"(?<id>\d+);#(?<text>[^;|^$]+)"); 
foreach (Match m in fieldValues) 
{ 
    if (m.Groups["text"].Value.Equals(someString)) 
    { 
     // Do stuff 
    } 
} 

उत्तर

10

आप LINQ के साथ अपने someString फ़िल्टर भी शामिल कर सकते हैं।

var matches = Regex.Matches(fieldValue, @"(?<id>\d+);#(?<text>[^;|^$]+)"); 
var textMatches = from Match m in matches 
        where m.Groups["text"].Value.Equals(someString) 
        select m; 

foreach (Match m in textMatches) 
{ 
    // Do stuff 
} 

ध्यान दें कि संकलक इस तरह एक प्रश्न तब्दील हो ...

var q = from MyType x in myEnum select x; 

... इस में ...

var q = from x in myEnum.Cast<MyType>() select x; 

... इसलिए दोनों प्रकार और सहित Cast<T>() अनावश्यक है।

प्रदर्शन-वार, Cast<T>() सिर्फ एक स्पष्ट प्रकार का कलाकार करता है और मूल्य उत्पन्न करता है, इसलिए प्रदर्शन हिट नगण्य होगी। विरासत संग्रह के लिए जहां आप सुनिश्चित नहीं हैं कि सभी सदस्य वांछित प्रकार के हैं, आप इसके बजाय OfType<T>() का उपयोग कर सकते हैं।

+0

किसी कारण से मुझे नहीं लगता था कि यह काम करेगा क्योंकि मिलानकोलेक्शन सामान्य नहीं है। मुझे लगता है कि मैंने कोशिश की होनी चाहिए! संकलक अनुवाद की आपकी व्याख्या बहुत उपयोगी थी। –

3

कोशिश है।

IEnumerable<Match> query = from Match m in fieldValues.Cast<Match>() 
          select m; 

और घटना यदि आप कास्ट विधि का उपयोग नहीं करते संकलक IEnumerable करने के लिए "क्वेरी" के प्रकार का अनुमान लगा होगा।

var query = from Match v in fieldValues 
         select v;