2010-10-25 10 views
153

में कास्ट() और Oftype() का उपयोग करने के मैं Linq में एक Arraylist से IEnumerable के प्रकार के कास्टिंग और जो मामलों में उन्हें इस्तेमाल करने की सोच के दो तरीके के बारे में पता कर रहा हूँ?जब Linq

, उदा,

IEnumerable<string> someCollection = arrayList.OfType<string>() 

या

IEnumerable<string> someCollection = arrayList.Cast<string>() 

इन दोनों तरीकों और जहां मैं प्रत्येक मामले में आवेदन करना चाहिए के बीच क्या अंतर है?

उत्तर

236

OfType - केवल प्रकार x के तत्व लौटाएं।
Cast - सभी तत्वों को टाइप x में डालने का प्रयास करेंगे। अगर उनमें से कुछ इस प्रकार से नहीं कर रहे हैं आप उदाहरण के लिए InvalidCastException

संपादित
मिल जाएगा:

object[] objs = new object[] { "12345", 12 }; 
objs.Cast<string>().ToArray(); //throws InvalidCastException 
objs.OfType<string>().ToArray(); //return { "12345" } 
+0

इसके लिए चीयर्स।दोनों पहले से कोशिश की लेकिन दोनों के पास सभी प्रकार के तत्व अपेक्षित थे इसलिए मुझे अंतर क्यों नहीं दिखाई दे रहा था। –

+6

@SLaks सही ढंग से बताते हैं कि आपको 'Cast ' का उपयोग करना चाहिए जब आप यह सुनिश्चित करने के लिए जानते हैं कि संग्रह में केवल 'T' तत्व हैं। 'टाइप प्रकार '''' प्रकार की जांच के कारण धीमा है। यदि संग्रह 'IENumerable ' प्रकार का है, तो '' कास्ट करें, पूरे संग्रह को 'IENumerable ' के रूप में आसानी से डालेगा और इसे समझाए जाने से बचें; 'ऑफ टाइप ' अभी भी गणना करेगा। रेफरी: http://stackoverflow.com/questions/11430570/why-is-oftype-faster-than-cast – hIpPy

+19

यहां तक ​​कि ऐसे मामलों में जहां '.Cast () जब यह प्रगणित है', फेंक नहीं है यह ** ** 'ओएफटी टाइप ()' के बराबर नहीं है। कारण यह है कि ** 'शून्य 'मान ** हमेशा' ओएफटी टाइप ()' द्वारा छोड़े जाते हैं। एक उदाहरण: 'नई प्रणाली। चयन .अरेलेलिस्ट {"एबीसी", "डीफ़", शून्य, "घी",}। ओएफटी टाइप ()। गणना() 'केवल' 3' देगी; 'Cast () 'के साथ समान अभिव्यक्ति' 4' का मूल्यांकन करती है। –

2

Cast() संग्रह के सभी तत्वों (कास्ट करने के लिए कोशिश करेंगे और एक अपवाद है, तो तत्व फेंक होगा गलत प्रकार का है) जबकि OfType() उचित प्रकार के केवल तत्व लौटाएगा।

83

http://solutionizing.net/2009/01/18/linq-tip-enumerable-oftype/

मूल रूप से, कास्ट() इस तरह कार्यान्वित किया जाता है:

public IEnumerable<T> Cast<T>(this IEnumerable source) 
{ 
    foreach(object o in source) 
    yield return (T) o; 
} 

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

public IEnumerable<T> OfType<T>(this IEnumerable source) 
{ 
    foreach(object o in source) 
    if(o is T) 
     yield return (T) o; 
} 

लौटे गणन केवल तत्वों को सुरक्षित रूप से निर्दिष्ट प्रकार के डाली जा सकती है, शामिल होंगे: इस विचार पर एक कम कुशल अभी तक उपयोगी भिन्नता OfType() है।

2

ऑफ़टाइप तत्वों को केवल निर्दिष्ट प्रकार के केवल लौटने के लिए फ़िल्टर करेगा। यदि कोई तत्व लक्ष्य प्रकार पर नहीं डाला जा सकता है तो कास्ट क्रैश हो जाएगा।

26

यदि आपको पता है कि सभी आइटम string एस हैं तो आपको Cast<string>() पर कॉल करना चाहिए।
यदि उनमें से कुछ तार नहीं हैं, तो आपको अपवाद मिलेगा।

आपको OfType<string>() पर कॉल करना चाहिए यदि आपको पता है कि कुछ आइटम string एस नहीं हैं और आप उन आइटमों को नहीं चाहते हैं।
यदि उनमें से कुछ तार नहीं हैं, तो वे नए IEnumerable<string> में नहीं होंगे।

+0

यह उत्तर (वर्तमान में) एकमात्र ऐसा है जो किसी विधि का उपयोग करने के लिए एक स्पष्ट सलाह देता है। – CodeFox

2

कास्ट सभी वस्तुओं को दिए गए प्रकार टी में डालने का प्रयास करेगा। यह कास्ट असफल हो सकता है या अपवाद फेंक सकता है। ऑफटाइप मूल संग्रह का एक सबसेट लौटाएगा और केवल उन वस्तुओं को लौटाएगा जो टाइप टी

3

यह ध्यान दिया जाना चाहिए कि कास्ट (टी) का उपयोग अन्य LINQ फ़ंक्शंस के विपरीत IENumerable पर किया जा सकता है, इसलिए यदि कोई ऐसा मामला है आपको एक गैर-जेनेरिक संग्रह या एरेलेलिस्ट जैसे सूची पर LINQ का उपयोग करने की आवश्यकता है, आप एक IENumerable (टी) में कास्ट करने के लिए कास्ट (टी) का उपयोग कर सकते हैं जहां LINQ काम कर सकता है।