2010-02-23 16 views
13

के पहले तत्व प्राप्त करने के लिए कैसे वहाँ एक बेहतर तरीका है इस बात का IEnumerable प्रकार के पहले तत्व हो रही है:IEnumerable

foreach (Image image in imgList) 
{ 
    picture.Width = (short)image.Columns; 
    picture.Height = (short)image.Rows; 
    break; 
} 

इस प्रकार की सटीक घोषणा है:

public class ImageList : IEnumerable, IDisposable 
+0

आप जेनेरिक 'आईनेमरेबल ' का उपयोग क्यों नहीं करते हैं, इसलिए 'छविसूची' 'IENumerable 'से प्राप्त हो सकती है? –

+1

@ अरनिस: क्योंकि ImageMagick.net लाइब्रेरी में ImageLIst defien ... :) –

उत्तर

26
var firstImage = imgList.Cast<Image>().First(); 
+0

@ मार्क, कास्ट आवश्यक है .. क्या हम सिर्फ "var firstImage = ImgList.First()" का उपयोग नहीं कर सकते ?? – RameshVel

+4

@ रमेश: इस मामले में 'कास्ट' की आवश्यकता है क्योंकि 'प्रथम'' IENumerable 'के लिए लागू किया गया है लेकिन 'छविसूची' केवल 'IENumerable' लागू करता है। –

+1

@ रमेश वेल, आप imgList.First() का उपयोग नहीं कर सकते क्योंकि यह इसे कास्टिंग करने से पहले एक सामान्य आईनेमेरेबल नहीं है। – JonC

5

एक्सटेंशन .First() पहले आइटम को एक गणना में ले जाएगा। यदि संग्रह खाली है, तो यह एक अपवाद फेंक देगा। .FirstOrDefault() एक खाली संग्रह (संदर्भ प्रकार के लिए शून्य) के लिए एक डिफ़ॉल्ट मान वापस करेगा। अपने हथियार बुद्धिमानी से चुनें!

10

यदि आप LINQ का उपयोग नहीं कर सकते हैं तो आप सीधे imgList.GetEnumerator() द्वारा गणक प्राप्त कर सकते हैं और फिर पहले तत्व पर जाने के लिए .MoveNext() करें। .Current फिर आपको पहला तत्व देगा।

0

आपकी वर्तमान स्थिति पर थोड़ा अप्रासंगिक हो सकता है, लेकिन वहाँ भी एक .Single() और एक .SingleOrDefault() जो पहला तत्व देता है और अगर वहाँ संग्रह (.Single()) में ठीक एक तत्व नहीं है एक अपवाद फेंकता है या है अगर वहाँ अधिक कर रहे हैं संग्रह में एक तत्व से अधिक (.SingleOrDefault())।

यदि आपके पास तर्क है जो आपकी सूची में केवल एक (या शून्य) ऑब्जेक्ट्स पर निर्भर करता है तो यह बहुत उपयोगी हो सकता है। हालांकि मुझे संदेह है कि वे वही नहीं हैं जो आप यहां चाहते थे।

+0

असल में मैं लिंक को बहुत अच्छी तरह से जानता हूं, लेकिन 'आईनेमेरेबल' भ्रमित था क्योंकि नियमित रूप से 'आईनेमेरेबल ' के साथ काम करता था। –

0

मुझे एक समस्या थी जहां मैंने अपने डेटा स्रोत को बाइंडिंगसोर्स से एक इकाई फ्रेमवर्क क्वेरी में बदल दिया।

var query = dataSource as IQueryable; 
var value = query.Where("prop = @0", value).Cast<object>().SingleOrDefault(); 

इकाई ढांचे के साथ यह 'ऑब्जेक्ट' टाइप करने के लिए 'ग्राहक' प्रकार को कास्ट करने में असमर्थ है। LINQ से संस्थाएं केवल ईडीएम आदिम या गणना प्रकार कास्टिंग का समर्थन करती हैं।

वह वर्ग जहां मेरा कोड मॉडल के साथ lib के संदर्भ में नहीं था, इसलिए ...Cast<customer> संभव नहीं था।

वैसे भी मैं एक IEnumerable विस्तार जो प्रतिबिंब

public static object SingleOrDefault(this IEnumerable enumerable, Type type) 
    { 
     var method = singleOrDefaultMethod.Value.MakeGenericMethod(new[] { type }); 
     return method.Invoke(null, new[] { enumerable }); 
    } 

    private static Lazy<MethodInfo> singleOrDefaultMethod 
     = new Lazy<MethodInfo>(() => 
      typeof(Extensions).GetMethod(
       "SingleOrDefault", BindingFlags.Static | BindingFlags.NonPublic)); 

    private static T SingleOrDefault<T>(IEnumerable<T> enumerable) 
    { 
     return enumerable.SingleOrDefault(); 
    } 

प्रकार प्रति कैशिंग को लागू करने के प्रदर्शन में सुधार करने के लिए स्वतंत्र महसूस का उपयोग करता है के साथ इस दृष्टिकोण

var query = dataSource as IQueryable; 
var targetType = query.GetType().GetGenericArguments()[0]; 
var value = query.Where("prop = @0", value).SingleOrDefault(targetType); 

संयोजन के रूप में इस्तेमाल किया।