2015-05-27 10 views
10

है Iप्रकार परिवर्तनीय है।जांचें कि क्या IENumerable <object> IENumerable <int>

IEnumerable<object> items= new object[] { 1, 2, 3 }; 

यह जांचने का सबसे अच्छा तरीका क्या है कि यह IEnumerable<int> है?

मैं

typeof(IEnumerable<int>).IsAssignableFrom(items.GetType()) 
typeof(IEnumerable<int>).IsInstanceOfType(items) 
items is IEnumerable<int> 

की कोशिश की लेकिन, फिर से अधिक पैना उन सब के बारे में शिकायत।

मेरे मामले में, IEnumerable<object> itemsज्यादातर मामलों में टाइप IEnumerable<int> की है। और जब मैं IEnumerable<int> टाइप करता हूं और अन्य प्रकार के लिए कुछ और करता हूं तो मैं कुछ करना चाहता था।

+4

'आइटम' में प्रत्येक तत्व किसी भी प्रकार का हो सकता है, इसलिए आपको प्रत्येक तत्व को अलग-अलग जांचना होगा। आप जो चेक अब करते हैं वह केवल * प्रकार * पर लागू होता है जो सामग्री पर नहीं है। –

+3

आप क्या हासिल करने की कोशिश कर रहे हैं? मुझे लगता है कि सबसे आसान होगा 'valueA.All (item => आइटम int है)' लेकिन एक xy समस्या – Sayse

+0

की तरह लगता है INumerable ज्यादातर मामलों में 'IENumerable ' है, मैं टाइप करने पर कुछ करना चाहता था 'IENumerable ' और अन्य प्रकार के लिए कुछ और। – ANewGuyInTown

उत्तर

12

आप अगर एक IEnumerable<object> केवल ints शामिल जाँच करना चाहते हैं, तो आप Enumerable.All उपयोग कर सकते हैं:

var isInts = items.All(x => x is int); 
+1

के बीच कोई प्रकार या विरासत संबंध नहीं है, इसलिए, यह 'आइटम' में सभी मानों के माध्यम से लूप होगा और इसके प्रकार की जांच करेगा। मैं "बॉक्स से बाहर" समाधान की तलाश में था, लेकिन मुझे बहुत उम्मीद की जा रही है। आपके उत्तर के लिए धन्यवाद। मुझे इसका सहारा लेना पड़ सकता है। – ANewGuyInTown

+1

@ANewGuyInTown यदि आप निश्चित रूप से * जानते हैं * सभी आइटम एक ही प्रकार के हैं, तो आप 'Any' का उपयोग कर सकते हैं - यह पहले पुनरावृत्ति के बाद रुक जाएगा। –

+0

@GertArnold लेकिन वह पूरा बिंदु यह है कि वह * नहीं जानता :) –

3

आप इस तरह Cast या OfType उपयोग कर सकते हैं:

OfType:

बस का ध्यान देना चाहिए केवल के प्रकार के एक्स तत्वों लौटें।

कास्ट: सभी तत्वों को टाइप x में डालने का प्रयास करेंगे। आप InvalidCastException

items.Cast<int>(); 

या

items.OfType<int>(); 
+1

नोट: प्रकार का एक ही सूची वापस करने के लिए जरूरी नहीं है, और हालांकि यह शीर्षक का जवाब देता है, यह सवाल का जवाब नहीं देता है। – Sayse

+0

मैं एक अलग सूची/गणना करने के लिए 'कास्ट' नहीं करना चाहता, मैं सिर्फ – ANewGuyInTown

+1

@ANewGuyInTown जांचना चाहता हूं चेक को कोई समझ नहीं आता है। आपने एक वेरिएबल को परिभाषित किया है जिसमें कुछ भी हो सकता है - स्ट्रिंग्स और इनट्स दोनों। इस आईनेमेरेबल

5

क्योंकि Valuetypes do not support co or contravariance मिल जाएगा, तो उनमें से कुछ इस प्रकार से नहीं हैं। IEnumerable<object>IEnumerable<int> नहीं हो सकता - आपने इसे स्वयं साबित कर दिया क्योंकि आपको अपने IEnumerable<object> का उत्पादन करने के लिए एक कास्ट का उपयोग करना पड़ा, जो वास्तव में सभी int मानों को बॉक्स किया गया था। इसलिए R # एक संदिग्ध टाइपशेक की सही रिपोर्टिंग कर रहा है क्योंकि यह आपके कार्यों से निकला है कि आपके चेक हमेशा झूठे होंगे।

तो अंत में आपको प्रत्येक तत्व को व्यक्तिगत रूप से जांचना होगा यदि यह एक कास्ट का उपयोग करने से पहले एक इंट है या आप अपवाद में भाग लेंगे।

1

आप एक दूसरे के लिए सामान्य डाली नहीं कर सकते हैं, सिर्फ इसलिए कि प्रकार अन्य के आधार वर्ग है। तो Enumerable<object> से Enumerable<int> प्राप्त करने का कोई मौका नहीं है। पुन: शार्प शिकायत करता है क्योंकि अभिव्यक्ति कभी भी सच नहीं होगी।

आप

IEnumerable<object> items= ((IEnumerable)valueA).Cast<object>(); 

शायद आप जानते हैं कि आपके valueA पूर्णांकों से भर जाता है है, लेकिन आप भी अपने items में तार या तैरता डाल करने के लिए अनुमति दी जाती है। तो संकलक यह सुनिश्चित करने के लिए नहीं जान सकता कि सूची पूर्णांक का एक गणनीय है।

तो तुम, एक नया गणनीय बनाने के लिए की तरह Peyman से पहले जवाब (जो एक नई सूची, सिर्फ एक और गणनीय नहीं है):

items.OfType<int>(); 

यह केवल तत्व है जो पूर्णांक हैं वापस आ जाएगी और है कि आप यह सुनिश्चित करता है Enumerable<int>

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