2012-12-19 25 views
7

कई कस्टम Enumerable एक्सटेंशन के साथ PLINQ का लाभ उठाते हुए अन्य builtin संचालन के मामले में लागू किया जा सकता - उदाहरण के लिए इस तुच्छ सुविधा विधि:कस्टम Enumerable एक्सटेंशन

public static bool AnyOf<TElement>(this TElement item, IEnumerable<TElement> items) 
{ 
    return items.Any(a => EqualityComparer<TElement>.Default.Equals(a, item)); 
} 

अब यह किसी भी PLINQ क्वेरी वापस अनुक्रमिक आपरेशन के लिए विवश करेगा भले ही PLINQ भी एक किसी भी है - और बस सिर्फ एक हस्ताक्षर परिवर्तन के साथ बराबर है:

public static bool AnyOf<T>(this T item, ParallelQuery<T> items) 
{ 
    return items.Any(a => EqualityComparer<T>.Default.Equals(a, item)); 
} 

लेकिन मेरे लिए गंदा लगता है इस तरह यह डुप्लिकेट।

पहले तो मैंने सोचा था कि जैसे कुछ नीचे काम कर सकते हैं, लेकिन निश्चित रूप से यह^क्योंकि विस्तार तरीकों स्थिर तरीकों और इसलिए के रूप में करने का विरोध किया ParallelQuery.Any हस्ताक्षर के आधार पर संकलन समय पर किया जाता है Enumerable.Any कॉल करने के लिए निर्णय कर रहे हैं नहीं करता है।

public static bool AnyOf<TElement, TEnumerable>(this TElement item, TEnumerable items) 
    where TEnumerable : class, IEnumerable<TElement> 
{ 
    return items.Any(a => EqualityComparer<TElement>.Default.Equals(a, item)); 
} 

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


शायद एक सहायक है कि साथ में चलाना से लाभ होगा की एक बेहतर उदाहरण (जाहिर है श्रृंखलित किया जा सकता है, आदि) कुछ इस तरह है।

public static IEnumerable<string> ToStrings(this IEnumerable<object> ienum) 
{ 
    return ienum.Select(a=> a.ToString()); 
} 

^संकलक त्रुटि:

The type 'ParallelQuery<TElement>' cannot be used as type parameter 
'TEnumerable' in the generic type or method 
'AnyOf<TElement,TEnumerable>(TElement, TEnumerable)'. There is no 
implicit reference conversion from 'ParallelQuery<TElement>' to 
'IEnumerable<TElement>' 

इसके अलावा पर विचार के लायक है कि ParallelQuery की नहीं सभी/Enumerable तरीकों के बराबर हैं, भले ही वे संकलन है।

+0

वास्तविक सवाल क्या है? – jessehouwing

+1

उम्म, गलती। थोड़ा दूर ले गया: "क्या LINQ एक्सटेंशन लिखने का कोई तरीका है जो PLINQ के साथ भी काम करता है?"। – Fowl

+0

क्या आपके सभी एक्सटेंशन विधियां इस छोटी हैं? उनमें से कितने हैं? – svick

उत्तर

1

मैंने IQueryable/IEnumerable एक्सटेंशन लिखने के लिए समान किया है। सामान्य बिट्स को फैक्टर करने के लिए एक अभिव्यक्ति धारण करने वाले स्थिर चर घोषित करने और फिर उस अभिव्यक्ति को फ़ंक्शन के दो अलग-अलग संस्करणों से संदर्भित करने का प्रयास करना शामिल है। मेरे पास अब कोड नहीं है, और जब मैं किया गया था, तो यह बहुत बदसूरत था और मैं इससे संतुष्ट नहीं था। यहां एक मामूली उदाहरण है।

Expression<Func<PersonHistory, bool>> IsCurrent = (p) => p.Ends > DateTime.Now && p.Starts <= DateTime.Now; 

//Then in each Extension method: 
var query = db.PersonHistories.Where(IsCurrent); 

आखिरकार डी-डुप्लिकेशन का स्तर बिल्कुल अच्छा नहीं था, और जेनेरिक पैरामीटर द्वारा अधिक जटिल बना दिया जाएगा। शायद यह आपको एक विचार देगा हालांकि।

अन्य विचारों को देखने के लिए तत्पर हैं।

1

आप का उपयोग करके ऐसा कर सकता है तो तरह विधि (अर्थात क्रम स्विचिंग) के अंदर कास्टिंग जाँच:

public static bool AnyOf<TElement>(this TElement item, IEnumerable<TElement> items) 
{ 
    var parallelItems = items as ParallelQuery<TElement> 
    if(parallelItems != null) 
    { 
     return parallelItems.Any(a => EqualityComparer<TElement>.Default.Equals(a, item)) 
    } 
    //other runtime checks 
    .... 
    //else return default IEnumerable implementation 
    return items.Any(a => EqualityComparer<TElement>.Default.Equals(a, item)); 
} 
+0

यह कैसे मदद करता है? अभी भी इसका मतलब है कि आपके पास दो बार एक ही कोड है। – svick

+0

@svick ala 'मैं निष्कर्ष पर आया हूं कि प्रत्येक विधि की प्रति एक अलग हस्ताक्षर के साथ एक प्रति बनाये बिना असंभव है, लेकिन शायद कुछ ऐसा है जो मैंने याद किया है' और '" क्या LINQ एक्सटेंशन लिखने का कोई तरीका है जो काम करता है PLINQ के साथ?"उनका वास्तविक प्रश्न इसे दो बार नहीं लिख रहा है, लेकिन एक हस्ताक्षर होने के कारण गणितीय व्यवहार के आधार पर चालाक होगा, जिसके लिए यह एक समाधान – user1793607

+2

है लेकिन मेरा मानना ​​है कि ऐसा करने का मूल कारण कोड डुप्लिकेशन से बचाना है। – svick