2012-12-02 12 views
5

पर अज्ञात है मैं निम्नलिखित हस्ताक्षर के साथ एक छँटाई विस्तार विधि है:IEnumerable <T> को IEnumerable कास्ट जब टी संकलन समय

public static IEnumerable<T> CustomSort<T>(this IEnumerable<T> source, string sortProperties) 

हम इसे एक समय पहले लिखा था और इसे अपनी बात कर रहा है। अब मैं एक कस्टम नियंत्रण बना रहा हूं और डेटासोर्स प्रॉपर्टी एक आईनेमरेबल (गैर-जेनेरिक) है। क्या गैर-जेनेरिक IENumerable में ऑब्जेक्ट्स के प्रकार को प्राप्त करने का कोई तरीका है?

मुझे यकीन है कि "कस्टम नियंत्रण डेटा स्रोत को सॉर्ट करें" की समस्या दस लाख बार हल हो गई है, लेकिन मुझे बस समाधान नहीं मिल रहा है।

उत्तर

1

आप एक विस्तार विधि जो रनटाइम के दौरान सही प्रकार वापस आ जाएगी बना सकते हैं मैं तंत्र है कि मैं सामान्य विशेष IEnumerable<T> गैर पर छँटाई प्रदर्शन करने के लिए प्रयोग करेंगे जोड़ दिया है जेनेरिक IEnumerable

public static class SortingExtensions 
{ 
    public static IEnumerable<T> CustomSort<T>(this IEnumerable<T> source, string sortProperties) 
    { 
     // sort here 
    } 

    public static IEnumerable CustomSort(this IEnumerable source, string sortProperties) 
    { 
     var elementType = source.GetElementType(); 
     var genericElementType = typeof (IEnumerable<>).MakeGenericType(elementType); 

     var sortMethod = typeof (SortingExtensions).GetMethod(
      "CustomSort", 
      BindingFlags.Public | BindingFlags.Static, 
      null, 
      new [] {genericElementType, typeof (string)}, 
      null); 

     return (IEnumerable) sortMethod.Invoke(null, new object[] {source, sortProperties}); 
    } 

} 
+0

दिलचस्प दृष्टिकोण। मैं इसे भी कोशिश करूंगा। सॉर्ट विधि के बारे में, हम जो कुछ भी कर रहे हैं, उतना ही कम है, लेकिन हम कई गुणों के साथ सॉर्टिंग को ध्यान में रखते हैं, प्रत्येक अपनी दिशा के साथ। –

+0

मैंने आपके समाधान की कोशिश की, लेकिन enumerableType.GetGenericArguments()। पहला() एक StackOverflowException का कारण बनता है। (उम्र में इनमें से एक नहीं था! :)) –

+0

मुझे समस्या मिली। एक बार जब विधि सार्वजनिक स्थैतिक आईन्यूमेरेबल कस्टमसॉर्ट (इस आईनेमरेबल स्रोत, स्ट्रिंग सॉर्टप्रोपर्टीज) के माध्यम से जाती है तो इसे फिर से कहा जाता है, और यह एक infinate लूप बनाता है, या ऐसा लगता है। –

1

व्यक्तिगत रूप से, मैं सिर्फ

DataSource.Cast<object>() 

का प्रयोग करेंगे और उसके बाद आप एक IEnumerable<object> है कि आप अपने CustomSort<T> समारोह में उपयोग कर सकते हैं। मैं यहां मान रहा हूं कि यह कार्य पहले से ही मनमानी वस्तुओं को संभाल सकता है; दूसरे पैरामीटर नाम के आधार पर निर्णय ले रहा हूं कि मैं अनुमान लगा रहा हूं कि आप इसमें प्रतिबिंब का उपयोग कर रहे हैं, इसलिए यह ठीक होना चाहिए। बस सुनिश्चित करें कि यह प्रत्येक ऑब्जेक्ट के GetType() का उपयोग करता है जब इसे प्रतिबिंबित करता है, typeof(T) नहीं, क्योंकि typeof(T) स्पष्ट रूप से object होगा और इसे वास्तविक वस्तु के फ़ील्ड की सूची नहीं मिलेगी।

बेशक

, यदि आप वास्तव में संकलन समय पर डेटा स्रोत में सभी वस्तुओं के प्रकार पता है, आप के बजाय उस प्रकार का उपयोग करना चाहें, जैसे:

DataSource.Cast<Customer>() 
+0

आप MoveNext() के बारे में सही हैं। जब मैंने इस पोस्ट को बनाया था तब तक मैंने उस पंक्ति को पहले ही हटा दिया है, इसलिए मैं स्मृति से लिख रहा था। कास्ट के बारे में <>, मैं इसे आज़माउंगा। धन्यवाद! –

+0

@EladLachmi: ठीक है, तो मैं आपके प्रश्न से उस हिस्से को हटाने के लिए स्वतंत्रता ले जाऊंगा। – Timwi

+0

कस्टमसोर्ट फ़ंक्शन लैम्ब्डा अभिव्यक्ति के रूप में सॉर्ट बनाने के लिए प्रतिबिंब में टाइपोफ़ (टी) का उपयोग करता है। मैं कुछ नया बनाने की बजाय, हमारे पास जो कुछ भी है, उसका लाभ उठाना चाहता हूं (जिसे क्यूए, इत्यादि आदि के माध्यम से जाना होगा ... आप जानते हैं कि यह कैसा है :)) –

4

वहाँ एक बुनियादी मुद्दा यहाँ है कि एक प्रकार एक ही समय में एकाधिक टी के लिए IENumerable-of-T लागू कर सकता है। लेकिन अगर हम उस मामले बाहर करते हैं, एक मुखर दृष्टिकोण है:

void Evil<T>(IEnumerable<T> data) {...} 

IEnumerable source = ... 
dynamic cheeky = source; 
Evil(cheeky); 

यह मूलतः डीएलआर इस समस्या को offloads, दे अपने ईविल के- टी विधि आराम से।

public static class LinqExtensions 
{ 
    public static Type GetElementType(this IEnumerable source) 
    { 
     var enumerableType = source.GetType(); 
     if (enumerableType.IsArray) 
     { 
      return enumerableType.GetElementType(); 
     } 
     if (enumerableType.IsGenericType) 
     { 
      return enumerableType.GetGenericArguments().First(); 
     } 
     return null; 
    } 
} 

अपडेट::

+1

यह मानता है कि 'स्रोत' वास्तव में 'आईन्यूमेरेबल ' कुछ 'टी' के लिए; जेनेरिक से पहले .NET दिनांक में कई डेटा स्रोत और इस प्रकार वास्तव में केवल 'IENumerable' को लागू करते हैं, इस मामले में आपका कोड' RuntimeBinderException' के साथ क्रैश हो जाता है। – Timwi

+0

@Timwi सवाल "कास्टिंग" के बारे में पूछता है। यह केवल तभी संभव है जब यह वास्तव में कुछ टी के लिए सामान्य संस्करण लागू करता है। मैं आपसे असहमत नहीं हूं - मैं बस इतना कह रहा हूं कि यह निर्भरता प्रश्न में निहित है। –

+0

@ टिमवी - मार्क अपनी धारणा में सही है कि गैर-जेनेरिक आईनेमेरेबल (डेटासोर्स) की उत्पत्ति कुछ टी के की सूची है, जो संकलन समय पर मुझे अज्ञात है।इस प्रकार इसे IENumerable लागू करना चाहिए। –

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

  • कोई संबंधित समस्या नहीं^_^